OAuth2 密码模式之服务器实现

Posted Mr.DongYang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OAuth2 密码模式之服务器实现相关的知识,希望对你有一定的参考价值。

第一步:配置数据库 ,固定创建三张表 ,OAuth2 框架需要默认使用这三张表

我使用的时mysql,工具为navcat

 

CREATE TABLE `oauth_access_token` (
  `token_id` varchar(256) DEFAULT NULL,
  `token` blob,
  `authentication_id` varchar(250) NOT NULL,
  `user_name` varchar(256) DEFAULT NULL,
  `client_id` varchar(256) DEFAULT NULL,
  `authentication` blob,
  `refresh_token` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`authentication_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
----------
CREATE TABLE `oauth_client_details` (
  `client_id` varchar(250) NOT NULL,
  `resource_ids` varchar(256) DEFAULT NULL,
  `client_secret` varchar(256) DEFAULT NULL,
  `scope` varchar(256) DEFAULT NULL,
  `authorized_grant_types` varchar(256) DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) DEFAULT NULL,
  `authorities` varchar(256) DEFAULT NULL,
  `access_token_validity` int(11) DEFAULT NULL,
  `refresh_token_validity` int(11) DEFAULT NULL,
  `additional_information` varchar(4096) DEFAULT NULL,
  `autoapprove` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
----------
CREATE TABLE `oauth_refresh_token` (
  `token_id` varchar(256) DEFAULT NULL,
  `token` blob,
  `authentication` blob
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

第二步:IDEA+maven+springboot 集成OAuth2
这是服务器工程目录

 

 1.pom中配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>OauthText</artifactId>
        <groupId>OauthText</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>OAuthService</artifactId>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
          <!-- Spring Security Oauth2 -->
          <dependency>
              <groupId>org.springframework.security.oauth</groupId>
              <artifactId>spring-security-oauth2</artifactId>
          </dependency>

      </dependencies>

</project>

 

 2.进行AuthorizationServerConfiguration.java 进行基本配置

 

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Bean // 声明TokenStore实现
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Bean // 声明 ClientDetails实现
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .jdbc(dataSource);
    }

    @Override // 配置框架应用上述实现
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
        endpoints.tokenStore(tokenStore());
        endpoints.userDetailsService(userService);
//         配置TokenServices参数
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(endpoints.getTokenStore());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
        tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
        tokenServices.setAccessTokenValiditySeconds( (int) TimeUnit.DAYS.toSeconds(1)); // 1天
        endpoints.tokenServices(tokenServices);
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setSupportRefreshToken(true); // support refresh token
        tokenServices.setTokenStore(tokenStore); // use jdbc token store
        return tokenServices;
    }

 

 

 3.ResourceServerConfiguration.java 进行配置

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").authenticated()
                .anyRequest().authenticated();
    }

}

 

 

 4.WebSecurityConfiguration.java 进行配置

@Configuration
public class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {

    private final UserService userService;

    @Autowired
    public WebSecurityConfiguration(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);

    }

}

 

 5.进行自定义拦截配置
在service接口中

service 简单实现代码

 

@Service
public class UserServiceImpl implements UserService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("===================获取到token已进入自定义验证:"+username);
        // 可以进行数据库请求,这里进行模拟
              User user = new User();
              user.setUsername("110");
              user.setPassword("110119");
        if (user == null) {
            System.out.println("==================="+username);
            throw new UsernameNotFoundException("Could not find the user \'" + username + "\'");
        }
        return new CustomUserDetails(user, true, true, true, true, null);
    }
}

6.CustomUserDetails OAuth2 提供方法进行配置

public class CustomUserDetails extends User implements UserDetails {

    private static final long serialVersionUID = 1702923242319850756L;

    private final boolean enabled;
    private final boolean accountNonExpired;
    private final boolean credentialsNonExpired;
    private final boolean accountNonLocked;
    private final Set<GrantedAuthority> authorities;

    public CustomUserDetails(User user, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
        if (user != null
                && !StringUtils.isBlank(user.getUsername())
                && !StringUtils.isBlank(user.getPassword())) {
            setUsername(user.getUsername());
            setPassword(user.getPassword());
            this.enabled = enabled;
            this.accountNonExpired = accountNonExpired;
            this.credentialsNonExpired = credentialsNonExpired;
            this.accountNonLocked = accountNonLocked;
            this.authorities = Collections.unmodifiableSet(new HashSet<>(CollectionUtils.emptyIfNull(authorities)));
        } else {
            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
        }
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    @Override
    public Set<GrantedAuthority> getAuthorities() {
        return authorities;
    }
}

这是Controller 配置只要访问log 就会被OAuth2 进行拦截验证

@RestController
@RequestMapping("/")
public class TextController {

    @PostMapping(value = "/log")
    public String  saveCuringEvidence(@RequestBody User user){
        System.out.println("---------------------user:"+user.getUsername());
        return user.getUsername();
    }

}

 

 第三部:好了接下来进行postmain工具 模拟进行请求 url为你的域名+/oauth/token 获取token
1.首先配置客户端密码

2.而username和password 需要在刚刚建立的数据库进行自定义配置

 

 3.模仿form表单进行配置

 

 4.上面的账户和密码是自定义验证时需要的信息要和service里的账户和密码一致
成功之后
获取的access_token,复制下来

 

 5.模仿客户端根据token请求数据

 

 

 成功请求到数据 收工。。。。
OAuth2.0 配套客户端实现 :http://www.cnblogs.com/memoryXudy/p/7805217.html

 源码:https://gitee.com/xdymemory00/Security-OAuth2-MiMaMoShi.git

以上是关于OAuth2 密码模式之服务器实现的主要内容,如果未能解决你的问题,请参考以下文章

Springboot2.0 + OAuth2.0之授权码模式

#yyds干货盘点# springboot整合Oauth2,GateWay实现网关登录授权验证

在ASP.NET中实现OAuth2.0之了解OAuth

Spring Security OAuth2 Demo —— 密码模式(Password)

Spring Security OAuth2 Demo —— 客户端模式(ClientCredentials)

OAuth2.0 - 简化模式密码模式客户端模式讲解