org.springframework.boot
1.创建授权码客户端
因为之前密码模式和客户端模式没有问题,所以直接配置授权码客户端,在授权服务器
@EnableAuthorizationServer AuthorizationServerConfig 中配置 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource) // .withClient(“client”) // .secret(passwordEncoder.encode(“123456”)) // .authorizedGrantTypes(“password”, “refresh_token”)//允许授权范围 (密码授权和刷新令牌) // .authorities(“ROLE_ADMIN”, “ROLE_USER”)//客户端可以使用的权限 // .scopes(“read”, “write”) // .accessTokenValiditySeconds(7200) // .refreshTokenValiditySeconds(10000) // // //客户端模式 // .and().withClient(“client_1”) // .secret(passwordEncoder.encode(“123456”)) // .authorizedGrantTypes(“client_credentials”) // .scopes(“read”, “write”) // .authorities(“client_credentials”) // .accessTokenValiditySeconds(7200) // // //授权码模式 // .and() .withClient(“client_code”) .secret(passwordEncoder.encode(“123456”)) .authorizedGrantTypes(“authorization_code”, “refresh_token”, “password”, “implicit”) .scopes(“all”) .authorities(“ROLE_ADMIN”) .redirectUris(“http://ww.baidu.com”) .accessTokenValiditySeconds(1200) .refreshTokenValiditySeconds(50000); }
将前两种客户端先注释掉,启动。
注意:oauth2.0 的授权客户端可以自行在数据库进行配置,如果代码中配置,第二次启动会报主键冲突。
@Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); }
配置好后这样既可。
浏览器中请求:
- response_type:表示授权类型,必选项,此处的值固定为"code"
- client_id:表示客户端的ID,必选项
- redirect_uri:表示重定向URI,可选项
- scope:表示申请的权限范围,可选项
- state:可选项,表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
但是后台报错:
这个问题困扰我很长时间,经过查找资料了解了大概是oautho内部过滤器拦截顺序的原因,却不知道如何修改,
有篇博客说在application.properties,中添加security.oauth2.resource.filter-order = 3,但是添加后没有作用,按住ctrl 点击提示找不到,故推断是版本的问题,查看资料说spring boot 2.0 版本oauth2.0 做了许多更新。
在http://聊聊spring security oauth2的几个endpoint的认证 中
小结
需要保护/oauth/authorize以及/oauth/confirm_access这两个endpoint,当然主要是/oauth/authorize这个。
由于其他几个/oauth/开头的认证endpoint配置的认证优先级高于默认的WebSecurityConfigurerAdapter配置(order=100),
因此默认的可以这样配置
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http .requestMatchers().antMatchers(“/oauth/“,”/login/”,“/logout/**”) .and() .authorizeRequests() .antMatchers(“/oauth/**”).authenticated() .and() .formLogin().permitAll(); //新增login form支持用户登录及授权 } }
把整个/oauth/**保护进来
所以对代码做了修改,能够跳转到登录页面了,但是登录成功后没有跳转到redirect_uri=http://ww.baidu.com,测试几次没找到原因推测可能还是配置顺序的原因,突然想到看到过@Order的注解
ResourceServerConfiguration 和 SecurityConfiguration上配置的顺序, SecurityConfiguration一定要在ResourceServerConfiguration 之前,因为spring实现安全是通过添加过滤器(Filter)来实现的,基本的安全过滤应该在oauth过滤之前, 所以在SecurityConfiguration设置@Order(2), 在ResourceServerConfiguration上设置@Order(6)
配上之后测试成功终于出先了想要的结果。重新请求上边地址
返回:
拿着code去请求access_token:
localhost:18088/oauth/token?client_id=client_code&grant_type=authorization_code&redirect_uri=http://ww.baidu.com&client_secret=123456&code=nBYrX5
然后就可以拿着access_token 去请求资源了 如:http://localhost:18088/admin/me?access_token=27e23009-fe2a-4943-85a4-301bfa71c841
在请求头带上token,key:Authorization value: bearer + " "+token
注意:一个code 只能使用一次否则会报错
如:
当Token过期,刷新token:http://localhost:18088/oauth/token?grant_type=refresh_token&refresh_token=6d3a556f-377e-4be5-80bf-84e50390b557&client_id=client_code&client_secret=123456
OK了。程序不是很完善也不完美,还有很多问题没有搞懂。希望大牛可以指教!!
最后贴一下WebSecurityConfig 和ResourceServerConfig 代码
/** • 用于保护oauth相关的endpoints,同时主要作用于用户的登录(form login,Basic auth) */ @Order(2) @Configuration @EnableWebSecurity //@EnableGlobalMethodSecurity(prePostEnabled = true)//这个注解,可以开启security的注解,我们可以在需要控制权限的方法上面使用@PreAuthorize,@PreFilter这些注解 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Value(“${server.servlet.session.cookie.name}”) private String appCookieName; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override