spring security实战 5-使用密码模式(password grant type)保护资源

写在开篇

本改编课程基于《OAuth 2.0 Cookbook_Protect Your Web Applications using Spring Security-Packt Publishing(2017)》。这本书侧重经过一个个精简的小例子来学习,如何使用spring security和oauth2.0来保护你的资源。java

课程从第二章开始,在Chaptor2,咱们将学习如下内容:git

  1. 使用受权码模式(Authorization Code grant)保护资源github

  2. 支持隐式受权模式(Implicit grant)
  3. 使用密码模式(Resource Owner Password Credentials grant type )
  4. 配置客户端证书受权模式(Client Credentials grant)
  5. 支持refresh tokens
  6. 使用一个关系数据库来保存tokens和客户信息
  7. 使用redis保存token
  8. 实现客户端注册过程
  9. 中途破坏Oauth 2.0 Provider
  10. 使用Gatling,经过共享数据库测试token的验证过程

​ 本例咱们将学习如何配置密码模式,在实践中应该避免使用这种模式,由于这种模式客户端将拿到用户凭证,而这正是应该由Oauth 2.0经过access 代理来解决的事情。从用户凭证共享模式迁移到Oauth 2.0模式时,咱们能够选择这种策略。当客户端与Oauth 2.0受权中心在同一solution下(充分信任客户端的状况下)时使用会较为安全。web

Getting ready

Java8+maven
能够从https://github.com/PacktPubli... 下载项目源码,这个是书籍官方例子,亲自作过跑过,因此能够放心下载使用。redis

How to do it…

如下步骤将指导你,使用Spring Security OAuth2 配置一个受权中心和一个资源服务器:spring

1.使用Spring Initializr 新建一个Springboot工程,加入web,security依赖。
2.打开pom.xml,加入如下依赖:数据库

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId> 
</dependency>

3.打开application.properties文件,输入:json

security.user.name = adolfo

security.user.password = 123segmentfault

4.新建UserProfile类与UserController类,内容与《学习3》中一致
5.新建OAuth2ResourceServer类,内容与《学习3》中一致
6.新建OAuth2AuthorizationServer类:api

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("clientapp")
            .secret("123456") 
            .redirectUris("http://localhost:9000/callback")
            .authorizedGrantTypes("password") 
            .scopes("read_profile", "read_contacts"); 
    }
}

7.与《学习3》惟一不一样的就是authorizedGrantType的设置,看上去和前两种模式的设置差很少,可是当你直接运行应用时就会报错:

{ 
    "error": "unsupported_grant_type",
     "error_description": "Unsupported grant type: password"
}

8.那是由于,密码模式须要在OAuth2AuthorizationServer 中配置AuthenticationManager

这是完整的OAuth2AuthorizationServer 类:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends
        AuthorizationServerConfigurerAdapter {

    @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("clientapp")
            .secret("123456")
            .authorizedGrantTypes("password")
            .scopes("read_profile", "read_contacts");
    }

}

如今,咱们能够启动项目了

How it works…

当咱们使用@EnableAuthorizationServer@EnableResourceServer这两个注解时,已经经过spring security配置上oauth2.0的全部支持,正如前几个课程所示。最大的不一样,是咱们在OAuth2AuthorizationServer中注入了authenticationManager 实例。咱们之因此要使用这个实例是由于,受权中心在对第三方,携带access token的请求作出回应时,须要验证资源全部者的证书。

处理配置上的不一样,在验证流程上也有所不一样。在使用密码模式时,用户(或者称为资源全部者)必须发送凭证(用户名,密码),而这些操做将会在客户端的掌控下。所以,在使用这种模式与客户端和服务端交互时,须要资源全部者必须十分信任客户端。例如,你做为资源全部者与facebook的官方客户端交互,以后有转为与facebook的服务端作交互。

如今,咱们来看看,如何使用密码模式来获取资源:

1.首先发送如下请求:

curl -X POST --user clientapp:123456 <http://localhost:8080/oauth/token> -H "accept: application/json" -H "content-type: application/x-www-formurlencoded" -d "grant_type=password&username=adolfo&password=123&scope=read_profile"

或者使用postman:
图片描述

图片描述

图片描述

2.在上一步,咱们拿到了access token,如今咱们就可使用这个token来获取资源了,注意,咱们在以前没有设置token的过时时间,Spring Security OAuth2默认是43200s。咱们应该根据受权模式的不一样,设置不一样的过时时间,例如隐式模式就应该使用短一些的过时时间。好了,如今咱们来请求资源:
图片描述

curl -X GET <http://localhost:8080/api/profile> -H "authorization: Bearer 28405009-b53d-4e52-bfc3-c8889a477675"

There's more…

​ 尽管咱们建议尽可能不要使用密码模式,可是若是当你交互的客户端与服务端(验证中心)都在一个范围内(公司/部门/名下)的时候,能够大胆使用。须要注意的是,客户端不该保留用户的用户名和密码。

相关文章
相关标签/搜索