Springcloud+springsecurity+oauth2微服务统一授权认证
总共搭建授权微服务、学生微服务
1.引入pom
<dependencyManagement>
<dependencies>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.授权服务器授权编写(基于内存)
@Configuration
@EnableAuthorizationServer //授权服务a1
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
//配置客户端详情a2
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//基于内存存储
clients.inMemory()
//客户端id
.withClient("c1")
//客户端秘钥
.secret(new BCryptPasswordEncoder().encode("secret"))
//可访问的资源列表
.resourceIds("res1")
//客户端授权类型
.authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")
//授权范围,就是服务、读写权限等
.scopes("all")
//跳转到授权页面
.autoApprove(false)
//回调地址
.redirectUris("http://www.baidu.com");
}
@Autowired
TokenStore tokenStore;
@Autowired
ClientDetailsService clientDetailsService;
// a4客户端令牌服务
@Bean
public AuthorizationServerTokenServices tokenServices(){
DefaultTokenServices services=new DefaultTokenServices();
//客户端信息服务
services.setClientDetailsService(clientDetailsService);
//是否产生刷新令牌
services.setSupportRefreshToken(true);
//令牌存储策略tokenConfig.tokenService()
services.setTokenStore(tokenStore);
//令牌默认有效期
services.setAccessTokenValiditySeconds(7200);
//刷新令牌默认有效期3天
services.setRefreshTokenValiditySeconds(259200);
return services;
}
//令牌访问端点a5
@Autowired
AuthorizationCodeServices authorizationCodeServices;
@Autowired
AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
//密码模式
.authenticationManager(authenticationManager)
//授权码需要
.authorizationCodeServices(authorizationCodeServices)
//服务端
.tokenServices(tokenServices())
//允许放行请求
.allowedTokenEndpointRequestMethods(HttpMethod.POST, HttpMethod.GET);
}
//令牌访问安全策略a6
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
//oatuh/token_key公开
.tokenKeyAccess("permitAll()")
//检验令牌oatuh/check_token
.checkTokenAccess("permitAll()")
//表单认证申请令牌
.allowFormAuthenticationForClients();
}
}
3.配置授权码存储策略、加密方式
@Configuration
public class TokenConfig {
//a3令牌策略
@Bean
public TokenStore tokenService(){
return new InMemoryTokenStore();
}
设置授权码模式的授权码如何 存取,这里采用内存方式
@Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4.配置拦截器securi
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//加密工具类
@Autowired
private BCryptPasswordEncoder bcryptPasswordEncoder;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
private SuccessHandler successHandler;
@Autowired
private FailureHandler failureHandler;
@Autowired
private LogoutHandler logoutHandler;
//安全拦截器a7
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().formLogin()
.loginProcessingUrl("/login").permitAll()
.successHandler(successHandler).permitAll()
.failureHandler(failureHandler).permitAll().and()
.logout().logoutSuccessHandler(logoutHandler).and()
.authorizeRequests()
.antMatchers("/**").permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password(bcryptPasswordEncoder.encode("123456")).roles("ADMIN")
.and()
.withUser("user").password(bcryptPasswordEncoder.encode("123456")).roles("USER");
}
}
5.配置启动类
@EnableDiscoveryClient
@SpringBootApplication
public class UaaApplication {
public static void main(String[] args) {
SpringApplication.run(UaaApplication.class);
}
}
6.配置application.yml
server:
port: 8500
spring:
application:
name: oauth-server
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
#暴露监控
management:
endpoints:
web:
exposure:
include: '*'
7.测试获取token,检查token,授权token
获取token post表单请求:http://127.0.0.1:8500/oauth/token
参数:
client_id:c1
client_secret:secret
username:admin
password:123456
grant_type:password
结果:
{
"access_token": "63ea77f9-44ad-468f-bc80-e6396e19c954",
"token_type": "bearer",
"refresh_token": "42caab7a-9bd6-47ff-8761-a88de1e999db",
"expires_in": 6464,
"scope": "all"
}
检查token get请求http://127.0.0.1:8500/oauth/check_token?token=63ea77f9-44ad-468f-bc80-e6396e19c954
结果
{
"aud": [
"res1"
],
"user_name": "admin",
"scope": [
"all"
],
"active": true,
"exp": 1660125310,
"authorities": [
"ROLE_ADMIN"
],
"client_id": "c1"
}
刷新token post请求 http://127.0.0.1:8500/oauth/token
参数:
client_id:c1
client_secret:secret
username:admin
password:123456
grant_type:password
refresh_token:63ea77f9-44ad-468f-bc80-e6396e19c954
结果
{
"access_token": "976bbbcf-dd38-4df8-9c69-51c9d34347e9",
"token_type": "bearer",
"refresh_token": "8ac13f11-b9a7-47b5-99b1-61b4bf507dbf",
"expires_in": 6893,
"scope": "all"
}
2.搭建学生服务
1.pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.ls.demo</groupId>
<artifactId>demo-commom</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--授权-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
2.配置资源服务器
@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {
//资源列表
public static final String RESOURCE_ID="res1";
//资源服务器a9
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID).tokenServices(tokenServices()).stateless(true);
}
//a11资源令牌解析服务
@Bean
public ResourceServerTokenServices tokenServices(){
//使用远程请求授权服务器的方式检验token的客户端id和密码
RemoteTokenServices services=new RemoteTokenServices();
services.setCheckTokenEndpointUrl("http://127.0.0.1:8500/oauth/check_token");
services.setClientId("c1");
services.setClientSecret("secret");
return services;
}
//校验授权范围a10
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**")
.access("#oauth2.hasScope('all')")
.and().csrf().disable()
//不用记录session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
3.业务请求
@RestController
@RequestMapping("/student")
public class StudentController {
/**
* 老师权限或学生权限
*/
@GetMapping("/grade")
@PreAuthorize("hasAnyAuthority('teacher','student')")
public Object rs(HttpServletRequest request){
Map<String,Object> map=new HashMap<>();
map.put("张三",100);
return map;
}
}
3.application.yml
server:
port: 8000
spring:
application:
name: school-server
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
4.启动类
@SpringBootApplication
@EnableDiscoveryClient
public class SchoolApplication {
public static void main(String[] args) {
SpringApplication.run(SchoolApplication.class);
}
}
5.测试
get请求获取学生信息:http://localhost:8000/student/grade
请求头Authorization:Bearer 63ea77f9-44ad-468f-bc80-e6396e19c954
结果:
{
"张三": 100
}
版权声明:本文为ls_636原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。