博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring security oauth2 password授权模式
阅读量:5740 次
发布时间:2019-06-18

本文共 9157 字,大约阅读时间需要 30 分钟。

  hot3.png

前面的一篇文章讲了spring security oauth2的client credentials授权模式,一般用于跟用户无关的,开放平台api认证相关的授权场景。本文主要讲一下跟用户相关的授权模式之一password模式。

回顾四种模式

OAuth 2.0定义了四种授权方式。

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)(主要用于api认证,跟用户无关)

maven

org.springframework.security.oauth
spring-security-oauth2
org.springframework.boot
spring-boot-starter-security

配置

security config

支持password模式要配置AuthenticationManager

@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {//需要正常运行的话,需要取消这段注释,原因见下面小节//    @Override//    public void configure(HttpSecurity http) throws Exception {//        http.csrf().disable();//        http.requestMatchers().antMatchers("/oauth/**")//                .and()//                .authorizeRequests()//                .antMatchers("/oauth/**").authenticated();//    }    //配置内存模式的用户    @Bean    @Override    protected UserDetailsService userDetailsService(){        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();        manager.createUser(User.withUsername("demoUser1").password("123456").authorities("USER").build());        manager.createUser(User.withUsername("demoUser2").password("123456").authorities("USER").build());        return manager;    }    /**     * 需要配置这个支持password模式     * support password grant type     * @return     * @throws Exception     */    @Override    @Bean    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }}

这个是比client credentials模式新增的配置,主要配置用户以及authenticationManager

auth server配置

@Configuration@EnableAuthorizationServer //提供/oauth/authorize,/oauth/token,/oauth/check_token,/oauth/confirm_access,/oauth/errorpublic class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {    @Override    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {        oauthServer                .tokenKeyAccess("permitAll()") //url:/oauth/token_key,exposes public key for token verification if using JWT tokens                .checkTokenAccess("isAuthenticated()") //url:/oauth/check_token allow check token                .allowFormAuthenticationForClients();    }        /**     * 注入authenticationManager     * 来支持 password grant type     */    @Autowired    private AuthenticationManager authenticationManager;    @Override    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {        endpoints.authenticationManager(authenticationManager);    }    @Override    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        clients.inMemory()                .withClient("demoApp")                .secret("demoAppSecret")                .authorizedGrantTypes("client_credentials", "password", "refresh_token")                .scopes("all")                .resourceIds("oauth2-resource")                .accessTokenValiditySeconds(1200)                .refreshTokenValiditySeconds(50000);}

这里记得注入authenticationManager来支持password模式

否则报错如下

➜  ~ curl -i -X POST -d "username=demoUser1&password=123456&grant_type=password&client_id=demoApp&client_secret=demoAppSecret" http://localhost:8080/oauth/tokenHTTP/1.1 400X-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYX-Application-Context: applicationCache-Control: no-storePragma: no-cacheContent-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 03 Dec 2017 07:01:27 GMTConnection: close{"error":"unsupported_grant_type","error_description":"Unsupported grant type: password"}

resource server 配置

@Configuration@EnableResourceServerpublic class ResourceServerConfig extends ResourceServerConfigurerAdapter {//    /**//      * 要正常运行,需要反注释掉这段,具体原因见下面分析//     * 这里设置需要token验证的url//     * 这些需要在WebSecurityConfigurerAdapter中排查掉//     * 否则优先进入WebSecurityConfigurerAdapter,进行的是basic auth或表单认证,而不是token认证//     * @param http//     * @throws Exception//     *///    @Override//    public void configure(HttpSecurity http) throws Exception {//        http.requestMatchers().antMatchers("/api/**")//                .and()//                .authorizeRequests()//                .antMatchers("/api/**").authenticated();//    }}

验证

请求token

curl -i -X POST -d "username=demoUser1&password=123456&grant_type=password&client_id=demoApp&client_secret=demoAppSecret" http://localhost:8080/oauth/token

返回

HTTP/1.1 200X-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYX-Application-Context: applicationCache-Control: no-storePragma: no-cacheContent-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 03 Dec 2017 04:53:40 GMT{"access_token":"4cfb16f9-116c-43cf-a8d4-270e824ce5d7","token_type":"bearer","refresh_token":"8e9bfbda-77e5-4d97-b061-4e319de7eb4a","expires_in":1199,"scope":"all"}

携带token访问资源

curl -i http://localhost:8080/api/blog/1\?access_token\=4cfb16f9-116c-43cf-a8d4-270e824ce5d7

或者

curl -i -H "Accept: application/json" -H "Authorization: Bearer 4cfb16f9-116c-43cf-a8d4-270e824ce5d7" -X GET http://localhost:8080/api/blog/1

返回

HTTP/1.1 302X-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYSet-Cookie: JSESSIONID=F168A54F0F3C3D96A053DB0CFE129FBF; Path=/; HttpOnlyLocation: http://localhost:8080/loginContent-Length: 0Date: Sun, 03 Dec 2017 05:20:19 GMT

出错原因见下一小结

成功返回

HTTP/1.1 200X-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYX-Application-Context: applicationContent-Type: text/plain;charset=UTF-8Content-Length: 14Date: Sun, 03 Dec 2017 06:39:24 GMTthis is blog 1

错误返回

HTTP/1.1 401X-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockCache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYCache-Control: no-storePragma: no-cacheWWW-Authenticate: Bearer realm="oauth2-resource", error="invalid_token", error_description="Invalid access token: 466ee845-2d08-461b-8f62-8204c47f652"Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 03 Dec 2017 06:39:28 GMT{"error":"invalid_token","error_description":"Invalid access token: 466ee845-2d08-461b-8f62-8204c47f652"}

WebSecurityConfigurerAdapter与ResourceServerConfigurerAdapter

二者都有针对http security的配置,他们的默认配置如下

WebSecurityConfigurerAdapter

spring-security-config-4.2.3.RELEASE-sources.jar!/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.java

@Order(100)public abstract class WebSecurityConfigurerAdapter implements		WebSecurityConfigurer
{ //......protected void configure(HttpSecurity http) throws Exception { logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); } //......}

可以看到WebSecurityConfigurerAdapter的order是100

ResourceServerConfigurerAdapter

spring-security-oauth2-2.0.14.RELEASE-sources.jar!/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java

public void configure(HttpSecurity http) throws Exception {		http.authorizeRequests().anyRequest().authenticated();	}

它的order是SecurityProperties.ACCESS_OVERRIDE_ORDER - 1 spring-boot-autoconfigure-1.5.5.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerProperties.java

/**	 * The order of the filter chain used to authenticate tokens. Default puts it after	 * the actuator endpoints and before the default HTTP basic filter chain (catchall).	 */	private int filterOrder = SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;

由此可见WebSecurityConfigurerAdapter的拦截要优先于ResourceServerConfigurerAdapter

二者关系

  • WebSecurityConfigurerAdapter用于保护oauth相关的endpoints,同时主要作用于用户的登录(form login,Basic auth)
  • ResourceServerConfigurerAdapter用于保护oauth要开放的资源,同时主要作用于client端以及token的认证(Bearer auth)

因此二者是分工协作的

  • 在WebSecurityConfigurerAdapter不拦截oauth要开放的资源
@Override    public void configure(HttpSecurity http) throws Exception {        http.csrf().disable();        http.requestMatchers().antMatchers("/oauth/**")                .and()                .authorizeRequests()                .antMatchers("/oauth/**").authenticated();    }
  • 在ResourceServerConfigurerAdapter配置需要token验证的资源
@Override    public void configure(HttpSecurity http) throws Exception {        http.requestMatchers().antMatchers("/api/**")                .and()                .authorizeRequests()                .antMatchers("/api/**").authenticated();    }

这样就大功告成

doc

  • (good)
  • (good)

转载于:https://my.oschina.net/go4it/blog/1584100

你可能感兴趣的文章
ThreadLocal和ThreadLocalMap源码分析
查看>>
8.27 题解
查看>>
AFNetworking 下载文件断点续传操作
查看>>
Linux定时器
查看>>
JS数组分页
查看>>
云时代,程序员将面临的分化
查看>>
收藏的博客 -- Qt/C++学习
查看>>
Vue-cli 构建项目 的`.vue`组件中, scss中添加背景图路径问题
查看>>
各种遍历写法的比较
查看>>
[实战]MVC5+EF6+MySql企业网盘实战(7)——文件上传
查看>>
hoj1833 truck history
查看>>
用豆瓣镜像解决pip安装慢的问题
查看>>
杭电 1873 看病要排队 (优先队列的应用)
查看>>
怎样推广自己的博客
查看>>
Windows 7快速定位照片方法
查看>>
山寨“苹果皮”上市或涉嫌侵权iPhon
查看>>
ASP.NET Core之跨平台的实时性能监控
查看>>
hadoop elementary course
查看>>
js获取名字为XX的标签
查看>>
[HNOI2015]实验比较
查看>>