基于之前的文章springboot和springsecurity整合OAuth2
略有修改
1. 授权模块修改OauthServerConfig配置文件
@Configuration @EnableAuthorizationServer public class OauthServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private DataSource dataSource; @Autowired private UserDetailsService userDetailsService; @Autowired private AuthenticationManager authenticationManager; @Autowired private PasswordEncoder passwordEncoder; private String SIGNING_KEY = "salt"; //从数据库中查询出客户端信息 @Bean public JdbcClientDetailsService clientDetailsService() { JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource); jdbcClientDetailsService.setPasswordEncoder(passwordEncoder); return jdbcClientDetailsService; } @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SIGNING_KEY); //对称秘钥,资源服务器使用该秘钥来验证 return converter; } //授权信息保存策略 @Bean public ApprovalStore approvalStore() { return new JdbcApprovalStore(dataSource); } //授权码模式专用对象 @Bean public AuthorizationCodeServices authorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); } //指定客户端登录信息来源 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //从数据库取数据 clients.withClientDetails(clientDetailsService()); } //检测token的策略 @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.allowFormAuthenticationForClients() //允许form表单客户端认证,允许客户端使用client_id和client_secret获取token .checkTokenAccess("permitAll()") //对校验token接口设置权限控制 .tokenKeyAccess("permitAll()") // 获取token请求不进行拦截 .passwordEncoder(passwordEncoder); } //OAuth2的主配置信息 @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .approvalStore(approvalStore()) .authenticationManager(authenticationManager) .authorizationCodeServices(authorizationCodeServices()) .tokenStore(tokenStore()) .userDetailsService(userDetailsService) .tokenServices(tokenService()) .allowedTokenEndpointRequestMethods(HttpMethod.POST); } @Bean public AuthorizationServerTokenServices tokenService() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setClientDetailsService(clientDetailsService()); tokenServices.setSupportRefreshToken(true); tokenServices.setTokenStore(tokenStore()); tokenServices.setAccessTokenValiditySeconds(10800); // 令牌默认有效期2小时 tokenServices.setRefreshTokenValiditySeconds(86400); // 刷新令牌默认有效期3天 //新增对jwt配置 TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter())); tokenServices.setTokenEnhancer(tokenEnhancerChain); return tokenServices; } }
2. 修改资源模块OauthResourceConfig配置文件
@Configuration @EnableResourceServer public class OauthResourceConfig extends ResourceServerConfigurerAdapter { @Autowired private DataSource dataSource; @Autowired private TokenStore tokenStore; private String SIGNING_KEY = "salt"; /** * 指定token的持久化策略 * 其下有 RedisTokenStore保存到redis中, * JdbcTokenStore保存到数据库中, * InMemoryTokenStore保存到内存中等实现类, * 这里我们选择保存在数据库中 * * @return */ @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SIGNING_KEY); //对称秘钥,资源服务器使用该秘钥来验证 return converter; } public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("product_api")//指定当前资源的id,非常重要!必须写! .tokenStore(tokenStore) //指定保存token的方式 .stateless(true); } public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() //指定不同请求方式访问资源所需要的权限,一般查询是read,其余是write。 .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')") .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')") .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')") .and() .headers().addHeaderWriter((request, response) -> { response.addHeader("Access-Control-Allow-Origin", "*");//允许跨域 if (request.getMethod().equals("OPTIONS")) {//如果是跨域的预检请求,则原封不动向下传达请求头信息 response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); } }); } //资源服务令牌解析服务 // @Bean // public ResourceServerTokenServices tokenService() { // //使用远程服务请求授权服务器校验token,必须指定校验token 的url、client_id,client_secret // RemoteTokenServices service = new RemoteTokenServices(); // service.setCheckTokenEndpointUrl("http://localhost:9001/oauth/check_token"); // service.setClientId("baidu"); // service.setClientSecret("12345"); // return service; // } }
主要讲原先的数据库认证改为jwt认证
3. 测试
1. 生成令牌
2. 校验令牌
3. 测试资源访问
4. 示例代码
来源:https://www.cnblogs.com/ifme/p/12192562.html