版权声明:转载请注明作者 https://blog.csdn.net/myth_g/article/details/86093273
其实很早就自己没事尝试过做一个oauth2协议的认证服务器项目,一直模仿别人写demo,然后最近再写,发现一些问题,然后也相应解决了.
一.授权码模式(springsecurity):
(1)配置服务器
@EnableAuthorizationServer
@Configuration
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(new InMemoryTokenStore());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("test")
.authorizedGrantTypes("authorization_code")
.scopes("all")
.redirectUris("www.baidu.com");
}
}
这里配置了使用springsecurity的验证管理器,并且将token存在本地缓存;创建一个本地客户端,支持授权模式;
(2)配置springsecurity权限管理:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(new MyFilter(),UsernamePasswordAuthenticationFilter.class);
}
}
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(" "," ",new ArrayList<>()));
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
这里配置了一系列验证方式...我这里无论如何都会登陆成功;(拦截设置成全部放行,获取验证码时候会报没权限,难道考虑安全必须通过验证才能获取code)
(3)获取code:
http://localhost:8080/oauth/authorize?client_id=test&redirect_uri=www.baidu.com&response_type=code
确认后得到code:http://localhost:8080/oauth/www.baidu.com?code=89IaNn
(4)通过code获取token:
http://localhost:8080/oauth/token?grant_type=authorization_code&code=89IaNn&client_id=client_1&client_secret=123456
得到token:
{
"access_token": "dd953e08-7076-429a-8e14-6a9aabcb792c",
"token_type": "bearer",
"expires_in": 7199,
"scope": "all"
}
2.配置分离的资源服务器:
(1)配置文件:
@Configuration
@EnableResourceServer
public class MyResourceConfig extends ResourceServerConfigurerAdapter {
@Primary
@Bean
public RemoteTokenServices tokenServices() {
final RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
tokenService.setClientId("client_1");
tokenService.setClientSecret("123456");
return tokenService;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authorizeRequests().anyRequest().authenticated();
}
}
此处配置了远程认证服务器响应参数;
@GetMapping("test")
public Object test(){
return "SUCCESS";
}
测试接口:默认全部没权限拦截;
(2)根据上面产生的token再次访问接口实现远程授权:
此时完成了一次授权码授权操作;(其中可以自定义授权页面等,加到自己业务中,后面有时间在研究)