介绍
关于什么是oauth2。网上有很多资料。我这里就提供一篇给读者,就不必多说。
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
实现功能
- 能实现简单的oauth2服务
- 能够实现授权码模式和密码模式的登录
系统环境配置
- JDK1.8+
- mysql5.6+
- Redis
开发步骤
主要引入的jar包
主要用oauth2包和redis包。要实现oauth2服务就必须引用oauth2包,引入redis主要存储token。
<!--oauth2,security -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
其他包读者可查阅源码了解。
认证服务器
在实现认证服务器中,往类上加上注解@Configuration
和
@EnableAuthorizationServer
即可完成简单的认证服务器。但我们可以完成一些个性化需求。这里我们可以把token存储到redis里面等等,可以设置token的有效时间。源码如下。
/**
* @author lvhaibao
* @description 认证服务器
* @date 2018/12/25 0025 10:39
*/
@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private MyUserDetailsServiceImpl userDetailsService;
@Autowired
private RedisConnectionFactory connectionFactory;
@Resource
private ClientLoadProperties clientLoadProperties;
/**
* 定义token的存储方式
*
* @return TokenStore
*/
@Bean
public TokenStore tokenStore() {
return new RedisTokenStore(connectionFactory);
}
/**
* 定义令牌端点上的安全性约 束
*
* @param oauthServer oauthServer defines the security constraints on the token endpoint.
* @throws Exception exception
*/
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
oauthServer.allowFormAuthenticationForClients();
}
/**
* 用于定义客户端详细信息服务的配置程序。可以初始化客户端详细信息,也可以只引用现有商店。
*
* @param clients a configurer that defines the client details service. Client details can be initialized, or you can just refer to an existing store.
* @throws Exception exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
if (ArrayUtils.isNotEmpty(clientLoadProperties.getClients())) {
for (ClientProperties config : clientLoadProperties.getClients()) {
builder
//设置客户端和密码
.withClient(config.getClientId()).secret(config.getClientSecret())
//设置token有效期
.accessTokenValiditySeconds(7 * 24 * 3600)
//设置refreshToken有效期
.refreshTokenValiditySeconds(7 * 24 * 3600)
//支持的认证方式
.authorizedGrantTypes("refresh_token", "authorization_code", "password").autoApprove(false)
//授权域
.scopes("app","write");
}
}
}
/**
* 定义授权和令牌端点以及令牌服务
*
* @param endpoints defines the authorization and token endpoints and the token services.
* @throws Exception exception
*/
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
//指定认证管理器
.authenticationManager(authenticationManager)
//用户账号密码认证
.userDetailsService(userDetailsService)
// refresh_token
.reuseRefreshTokens(false)
//指定token存储位置
.tokenStore(tokenStore());
}
WebSecurityConfig配置
由于spring oauth2自带有spring security。因此默认情况下,对所有的接口都添加认证。我们需要请求连接进行授权或不授权处理,个性化登录等等。源码如下
/**
* @author lvhaibao
* @description 浏览器配置
* @date 2018/12/25 0025 10:53
*/
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//表单登录
.formLogin()
//允许访问
.and().authorizeRequests().antMatchers("/hello").permitAll().anyRequest().authenticated()
//禁用跨站伪造
.and().csrf().disable();
}
}
测试结果
-
导入数据库,并创建一个用户。sql脚本在项目中可以找到。
-
启动项目,打开浏览器输入:http://127.0.0.1:8088/oauth/authorize?response_type=code&client_id=lvhaibao&redirect_uri=http://baidu.com&state=test&scope=app。 然后出现登录页面:
输入用户名和密码:lhb/123456。
- 然后出现授权页面如下:
勾选Approve,点击Authorize出现页面如下:
- 把上图中的code参数取下。访问:http://127.0.0.1:8088/oauth/token?grant_type=authorization_code&client_id=lvhaibao&client_secret=123456&redirect_uri=http://baidu.com&code=7v27VQ&scope=app。 其中code值为第三部中code的值。点击之后效果如下:
项目源码
https://gitee.com/lvhaibao/spring-lhbauth/tree/0bf91f6d8cc59ee5598e8f488d321d2242acfd5a/