1,创建一个springboot项目
我的版本使用的是springboot2.2.1版本
2,在pom文件中加入security和oauth2依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<!-- 这里不要使用2.4.0版本, 注解EnableAuthorizationServer在2.4.0版本中是弃用的 -->
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
3,创建WebSecurityConfigurerAdapter的实现类WebSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
*
* @author lixx
* @version 1.0
* @date 2020-05-18 14:19
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/r/r1").hasAnyAuthority("p1")
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
4,创建授权服务配置类AuthorizationServer.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* 授权服务
*
* @author lixx
* @version 1.0
* @date 2020-05-18 13:32
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
/**
* 令牌策略
*/
@Autowired
private TokenStore tokenStore;
/**
* 客户端详情服务
*/
@Autowired
private ClientDetailsService clientDetailsService;
/**
* 认证管理器 , 密码模式需要
*/
@Autowired
private AuthenticationManager authenticationManager;
/**
* 授权码模式, 需要
*/
@Autowired
private AuthorizationCodeServices authorizationCodeServices;
/**
* 用来配置客户端详情服务(ClientDetailsService),客户端详情信息在
* 这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息
*
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
// 使用本地的方式存储, 为了简易方便测试
.inMemory()
// 客户端id
.withClient("c1")
// 客户端密钥
.secret(new BCryptPasswordEncoder().encode("secret"))
// 客户端可以请求的资源列表, id
.resourceIds("res1")
// 该客户端允许的授权类型 authorization_code(授权码模式),password(密码模式),refresh_token(刷新令牌),implicit(简化模式),client_credentials(客户端模式)
.authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
// 允许的授权范围
.scopes("all")
// false 授权码模式时, 申请授权码时是跳转到授权页面, true 不跳转页面, 直接获取到授权码
.autoApprove(false)
//加上验证回调地址
.redirectUris("http://www.baidu.com");
}
/**
* 用来配置令牌(token)的访问端点和令牌服务(token services)
*
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
// 认证管理器
.authenticationManager(authenticationManager)
// 授权码管理器
.authorizationCodeServices(authorizationCodeServices)
// 令牌管理器
.tokenServices(tokenServices())
// 允许post 请求令牌
.allowedTokenEndpointRequestMethods(HttpMethod.POST);
}
/**
* 用来配置令牌端点的安全约束
*
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
//oauth/token_key是公开
.tokenKeyAccess("permitAll()")
//oauth/check_token公开
.checkTokenAccess("permitAll()")
//表单认证(申请令牌)
.allowFormAuthenticationForClients()
;
}
/**
* 管理令牌的服务
*
* @return
*/
@Bean
public AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices services = new DefaultTokenServices();
// 客户端详情 服务
services.setClientDetailsService(clientDetailsService);
// 是否刷新令牌
services.setSupportRefreshToken(true);
// 令牌策略
services.setTokenStore(tokenStore);
// 令牌有效期
services.setAccessTokenValiditySeconds(7200);
// 刷新令牌时间
services.setRefreshTokenValiditySeconds(259200);
return services;
}
/**
* 授权码服务
*/
@Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
}
5,AuthorizationServer类中的对象 TokenStore 和 AuthenticationManager 还没有注入到spring容器中
5.1,注入TokenStore bean到spring容器
创建令牌策略配置类TokenConfig.java,
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* 令牌策略
*
* @author lixx
* @version 1.0
* @date 2020-05-18 13:48
*/
@Configuration
public class TokenConfig {
@Bean
public TokenStore tokenStore() {
// 本地方式, 简化, 为了方便测试
return new InMemoryTokenStore();
}
}
5.2,注入AuthenticationManager到spring容器
在第3步的WebSecurityConfig.java配置类中加入bean
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
6,创建UserDetailsService的实现类AuthorizationUserDetailsService.java,UserDetailsService在获取用户信息时用到的
import com.familylinkedu.oauth2.domain.UserDto;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
/**
*
* @author lixx
* @version 1.0
* @date 2020-05-18 14:06
*/
@Service
public class AuthorizationUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDto userDto = new UserDto();
userDto.setId("1");
userDto.setMobile("10086");
userDto.setUsername("zhangsan");
// 密码是 123
userDto.setPassword("$2a$10$2km83mXcQezJ8v5aAHYoe.QzzmJfOg1gA7F8AU2wI71mlXcPukUJm");
String encode = new BCryptPasswordEncoder().encode(userDto.getPassword());
System.err.println(encode);
// 用户拥有的权限
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("p1"));
authorities.add(new SimpleGrantedAuthority("p3"));
userDto.setAuthorities(authorities);
return userDto;
}
}
UserDto对象如下:
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* @author lixx
* @version 1.0
* @date 2020-05-18 14:08
*/
@Data
public class UserDto implements UserDetails {
private String id;
private String username;
private String password;
private String mobile;
private List<GrantedAuthority> authorities = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
7,启动springboot项目
暴露如下url
http://localhost:8900/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com
效果如下:
拿到授权码
9,获取令牌, 使用授权码,post的方式访问 /oauth/token 接口
授权码模式:
密码模式:(不需要第8步)
客户端模式:(不需要第8步)
简化模式:(直接获取到令牌)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72561.html