SpringBoot2 整合 OAuth2 资源认证(保护)

环境:2.2.11.RELEASE + OAuth2 + Redis

  • pom.xml
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security.oauth.boot</groupId>
			<artifactId>spring-security-oauth2-autoconfigure</artifactId>
			<version>2.2.11.RELEASE</version>
		</dependency>
  • application.yml
server:
  port: 8088
---
spring:
  application:
    name: oauth-resource
---
spring:
  redis:
    host: localhost
    port: 6379
    password: 
    database: 1
    lettuce:
      pool:
        maxActive: 8
        maxIdle: 100
        minIdle: 10
        maxWait: -1
  • Domain对象(我们在认证服务上是把Users对象序列化存储到了Redis,所以这里还需要这个类,其实如果用了网关,这些认证就不需要在资源端进行了)
public class Users implements UserDetails, Serializable {

	private static final long serialVersionUID = 1L;

	private String id ;
	private String username ;
	private String password ;
}
  • 核心配置类
@Configuration
@EnableResourceServer
public class OAuthConfig extends ResourceServerConfigurerAdapter {  

	private static final Logger logger = LoggerFactory.getLogger(OAuthConfig.class) ;
	
	public static final String RESOURCE_ID = "gx_resource_id";  
	
	@Resource
    private RedisConnectionFactory redisConnectionFactory ;
	
    @Override  
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {  
        resources.resourceId(RESOURCE_ID) ;
        OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint();  
        oAuth2AuthenticationEntryPoint.setExceptionTranslator(webResponseExceptionTranslator());
        resources.authenticationEntryPoint(oAuth2AuthenticationEntryPoint) ;
        resources.tokenExtractor((request) -> {
        	String tokenValue = extractToken(request) ;
    		if (tokenValue != null) {
    			PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(tokenValue, "");
    			return authentication;
    		}
    		return null;
        }) ;
    }  
    private String extractToken(HttpServletRequest request) {
		// first check the header... Authorization: Bearer xxx
		String token = extractHeaderToken(request);
		// sencod check the header... access_token: xxx
		if (token == null) {
			token = request.getHeader("access_token") ;
		}
		// bearer type allows a request parameter as well
		if (token == null) {
			logger.debug("Token not found in headers. Trying request parameters.") ;
			token = request.getParameter(OAuth2AccessToken.ACCESS_TOKEN) ;
			if (token == null) {
				logger.debug("Token not found in request parameters.  Not an OAuth2 request.") ;
			} else {
				request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, OAuth2AccessToken.BEARER_TYPE);
			}
		}
		return token;
	}
    private String extractHeaderToken(HttpServletRequest request) {
		Enumeration<String> headers = request.getHeaders("Authorization");
		while (headers.hasMoreElements()) { // typically there is only one (most servers enforce that)
			String value = headers.nextElement();
			if ((value.toLowerCase().startsWith(OAuth2AccessToken.BEARER_TYPE.toLowerCase()))) {
				String authHeaderValue = value.substring(OAuth2AccessToken.BEARER_TYPE.length()).trim();
				// Add this here for the auth details later. Would be better to change the signature of this method.
				request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE,
						value.substring(0, OAuth2AccessToken.BEARER_TYPE.length()).trim());
				int commaIndex = authHeaderValue.indexOf(',');
				if (commaIndex > 0) {
					authHeaderValue = authHeaderValue.substring(0, commaIndex);
				}
				return authHeaderValue;
			}
		}
		return null;
	}
    
    @Override  
    public void configure(HttpSecurity http) throws Exception {  
    	http.csrf().disable() ;
    	http.requestMatcher(request -> {
    			String path = request.getServletPath() ;
    			if (path != null && path.startsWith("/demo")) {
					return true ;
				}
    			return false ;
        	})
    		.authorizeRequests()
    		.anyRequest()
    		.authenticated() ;
    }
    
    @Bean
    public TokenStore tokenStore() {
    	TokenStore tokenStore = null ;
    	tokenStore = new RedisTokenStore(redisConnectionFactory) ;
    	return tokenStore ;
    }
    
    @Bean  
    public WebResponseExceptionTranslator<?> webResponseExceptionTranslator() {  
        return new DefaultWebResponseExceptionTranslator() {
			@SuppressWarnings({ "unchecked", "rawtypes" })
			@Override
			public ResponseEntity translate(Exception e) throws Exception {
				ResponseEntity<OAuth2Exception> responseEntity = super.translate(e) ;
				ResponseEntity<Map<String, Object>> customEntity = exceptionProcess(responseEntity);
				return customEntity ;
			}  
        };  
    }  
    
    private static ResponseEntity<Map<String, Object>> exceptionProcess(
			ResponseEntity<OAuth2Exception> responseEntity) {
		Map<String, Object> body = new HashMap<>() ;
		body.put("code", -1) ;
		OAuth2Exception excep = responseEntity.getBody() ;
		String errorMessage = excep.getMessage();
		if (errorMessage != null) {
			errorMessage = "认证失败,非法用户" ;
			body.put("message", errorMessage) ;
		} else {
			String error = excep.getOAuth2ErrorCode();
			if (error != null) {
				body.put("message", error) ;
			} else {
				body.put("message", "认证服务异常,未知错误") ;
			}
		}
		body.put("data", null) ;
		ResponseEntity<Map<String, Object>> customEntity = new ResponseEntity<>(body, 
				responseEntity.getHeaders(), responseEntity.getStatusCode()) ;
		return customEntity;
	}  
}  

核心配置类主要完整,开启资源服务认证,定义我们需要保护的接口,token的存储对象及错误信息的统一处理。

  • 测试接口
@RestController
@RequestMapping("/demo")
public class DemoController {
	
	@GetMapping("/res")
	public Object res() {
		return "success" ;
	}
	
}

测试:

先直接访问token或者传一个错误的tokenj

SpringBoot2 整合 OAuth2 资源认证(保护)

 

接下先获取一个正确的token

SpringBoot2 整合 OAuth2 资源认证(保护)

 

SpringBoot2 整合 OAuth2 资源认证(保护)

 

成功了

 

完毕!!!

给个关注,转发呗,谢谢!

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

 

SpringBoot一个提升N倍性能的操作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值