springcloud-sso单点登陆(二)
2019-12-24 本文已影响0人
凌康ACG
单点登陆的实现方式有多种:
1、基于cas来做
2、spring cloud oauth2的spring全家桶
3、自定义jwt(不推荐)
下面我们基于spring全家桶来做一个单点登陆系统2019年12月23日最新springboot版本2.2.2.RELEASE;由于篇幅问题,我们分成两篇文章。
基于上一篇https://www.jianshu.com/p/80b125ea8e76
源码:https://github.com/xcocean/spring-cloud-sso
一、创建用户客户端
创建一个在根目录下创建business-user
文件夹,在business-user下创建pom.xml
:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qbccn</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.qbccn</groupId>
<artifactId>business-user</artifactId>
<description>用户中心</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- oauth2 server start-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- oauth2 server end-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<!-- 排除 tomcat-jdbc 以使用 HikariCP -->
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.qbccn.UseApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
关键配置如下:
package com.qbccn.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class UserResourceConfiguration extends ResourceServerConfigurerAdapter {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
//需要授权的路径
.antMatchers("/user/**").hasAnyRole("USER")
.antMatchers("/admin/**").hasAnyRole("ADMIN")
.anyRequest().permitAll(); //其他页面所有人能访问
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// 配置资源 ID --对应sso的资源id
resources.resourceId("backend-resources");
}
}
application.yml,由于sso服务使用了8080端口,这里改成8081端口
server:
port:8081
spring:
main:
allow-bean-definition-overriding: true
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/sso?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
hikari:
minimum-idle: 1
idle-timeout: 600000
maximum-pool-size: 10
auto-commit: true
pool-name: MyHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
security:
oauth2:
client:
client-id: client
client-secret: secret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
token-info-uri: http://localhost:8080/oauth/check_token
mybatis:
mapper-locations: classpath:mapper/*.xml
项目截图如下:
image.png
二、测试
启动项目后:浏览器访问http://localhost:8081/user/info/lk
我们用postman登陆拿到token:
image.png
带上token访问:http://localhost:8081/user/info/lk?access_token=fd3a7ca5-af58-48e7-8351-bc3272109189
image.png
lk
这个用户没有admin权限,我们访问admin看看image.png
可以看到我们被拒绝访问。用postman登陆admin获取token再访问:
image.png
http://localhost:8081/admin/userList?access_token=d5e43187-026e-4bb7-8af7-dade7b657f47
image.png
我们停止认证服务器再请求会报错,其中引入okhttp是打算从business-user做登陆的。
关于如何在oauth2 client拿到sso的用户登录信息,比如权限、角色、账号呀?在客户端直接调用即可,他会根据你请求的token去sso获取相关信息,我们不需要输入账号:
//拿用户名,类似普通项目的session get(username)
SecurityContextHolder.getContext().getAuthentication().getName();
前后端分离就是基于此完成,实际的场景并没有这么简单,有很多开发规范需要遵守。但是核心验证仍是这样,喜欢就点个赞吧_。