1、集成Oauth2,pom增加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1、增加会话控制处理接口及实现类:
public interface PermissionService {
/**
*
* @Title: hasPermission
* @Description: 请求鉴权
* @param @param request
* @param @param authentication
* @param @return
* @return boolean
* @throws
*/
boolean hasPermission(HttpServletRequest request, Authentication authentication);
}
@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {
private static Logger log = LoggerFactory.getLogger(PermissionServiceImpl.class);
/**
* 判断请求是否有权限
*
* @param request HttpServletRequest
* @param authentication 认证信息
* @return 是否有权限
*/
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
log.info("check request permission ==> " + request.getRequestURI());
/**
* 以下代码仅供本地开发联调时打开,生产打包注释掉这块代码
* 解决本地开发联调时跨域问题访问不到图片的问题,本地开发联调时,前端ajax访问静态文件流存在跨域OPTIONS请求,如果OPTIONS不被允许的话前端则不会发起真正的资源请求
* OPTIONS请求不带cookie,所以不能进行会话检查
*/
// Enumeration<String> names = request.getHeaderNames();
// log.info("===================================================================");
// while(names.hasMoreElements()){
// String name = (String) names.nextElement();
// log.info(name + ":" + request.getHeader(name));
// }
// log.info("===================================================================");
//
// if("OPTIONS".equals(request.getMethod())) {
// log.info("===================OPTIONS=====================================");
// return true;
// }
//校验会话
//获取请求Set-Cookie中的JSESSIONID的值
Cookie[] cookies = request.getCookies();
String sessionId = null;
if(cookies != null) {
for(Cookie cookie : cookies) {
if("JSESSIONID".equals(cookie.getName())) {
sessionId = cookie.getValue();
break;
}
}
}
//从redis获取会话
HttpSession session = new HttpSession();
session.setSessionId(sessionId);
if(!session.isAvailable()) {
log.info("会话超时,请重新登录");
return false;
}
return true;
}
}
3、将会话控制处理类配置到Oauth2中,新建配置类继承ResourceServerConfigurerAdapter
@Configuration
@EnableResourceServer
public class ResourceConfigurerAdapter extends ResourceServerConfigurerAdapter {
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
http
.authorizeRequests()
.antMatchers("/auth/oauth/token_key").denyAll()
.antMatchers(
//不做鉴权的URL
"/code/image",
"/admin/appInfo/query"
).permitAll()
.anyRequest()
.access("@permissionService.hasPermission(request, authentication)")
.and()
.csrf().disable();//允许跨域访问
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.expressionHandler(expressionHandler);
}
/**
* 异常问题
* #oauth2.throwOnError(@permissionService.hasPermission(request, authentication))
* #EL1057E: No bean resolver registered in the context to resolve access to bean 'permissionService'
*
* @param applicationContext ApplicationContext
* @return OAuth2WebSecurityExpressionHandler
*/
@Bean
public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
expressionHandler.setApplicationContext(applicationContext);
return expressionHandler;
}
}