文章目录
- 一、数据库部分
- 1. 创建数据库
- 2. 初始化数据脚本
- 二、搭建maven父工程认证授权模块
- 2.1. 创建一个maven项目
- 2.2. 引入依赖
- 三、搭建认证授权模块
- 3.1. 创建一个子maven项目
- 3.2. 引入依赖
- 3.3. 增加application.yaml
- 3.4. 增加数据库实体
- 3.5. 增加接口
- 3.6. 增加用户读取实现类
- 3.7. 增加授权服务配置
- 3.8. 增加web安全拦截
- 3.9. 增加controller
- 3.10. 启动类添加注解
一、数据库部分
1. 创建数据库
创建一个名称为Auth-serv数据库
2. 初始化数据脚本
create table oauth_client_details (client_id VARCHAR(256) PRIMARY KEY,resource_ids VARCHAR(256),client_secret VARCHAR(256),scope VARCHAR(256),authorized_grant_types VARCHAR(256),web_server_redirect_uri VARCHAR(256),authorities VARCHAR(256),access_token_validity INTEGER,refresh_token_validity INTEGER,additional_information VARCHAR(4096),autoapprove VARCHAR(256)
);create table oauth_client_token (token_id VARCHAR(256),token BLOB,authentication_id VARCHAR(256) PRIMARY KEY,user_name VARCHAR(256),client_id VARCHAR(256)
);create table oauth_access_token (token_id VARCHAR(256),token BLOB,authentication_id VARCHAR(256) PRIMARY KEY,user_name VARCHAR(256),client_id VARCHAR(256),authentication BLOB,refresh_token VARCHAR(256)
);create table oauth_refresh_token (token_id VARCHAR(256),token BLOB,authentication BLOB
);create table oauth_code (code VARCHAR(256), authentication BLOB
);create table oauth_approvals (userId VARCHAR(256),clientId VARCHAR(256),scope VARCHAR(256),status VARCHAR(10),expiresAt TIMESTAMP,lastModifiedAt TIMESTAMP
);-- customized oauth_client_details table
create table ClientDetails (appId VARCHAR(256) PRIMARY KEY,resourceIds VARCHAR(256),appSecret VARCHAR(256),scope VARCHAR(256),grantTypes VARCHAR(256),redirectUrl VARCHAR(256),authorities VARCHAR(256),access_token_validity INTEGER,refresh_token_validity INTEGER,additionalInformation VARCHAR(4096),autoApproveScopes VARCHAR(256)
);create table user
(id int auto_incrementprimary key,passwd varchar(265) not null,user_name varchar(256) not null,user_role varchar(255) not null
);INSERT INTO `user` VALUES ('1', '$2a$10$9zmzrQoHPe2LvU/ciYOh7eh0vpThlG0jfVnd95t/McLyLb9t5N3zG', 'ziya', 'ADMIN');
INSERT INTO `oauth_client_details` VALUES ('app', 'app', '$2a$10$by3F74LZAxBQLXCbESOS/eew8/7skdxvx5QdcJAMddfLISizAOXAe', 'web', 'implicit,client_credentials,authorization_code,refresh_token,password', 'http://www.baidu.com', 'ROLE_USER', null, null, null, null);
二、搭建maven父工程认证授权模块
2.1. 创建一个maven项目
创建一个名称为eshop-parent的maven父工程
2.2. 引入依赖
<?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"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><description>电商父模块,所有子模块依赖传递</description><modules><module>order-serv</module><module>product-serv</module><module>user-serv</module><module>stock-serv</module><module>shopcart-serv</module><module>auth-serv</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.gblfy</groupId><artifactId>eshop-parent</artifactId><version>1.0-SNAPSHOT</version><!--https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E--><properties><java.version>1.8</java.version><spring.cloud-version>Hoxton.SR9</spring.cloud-version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud-version}</version><type>pom</type><scope>import</scope></dependency><!--spring-cloud-alibaba 版本控制--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.6.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>
其他子模块可以先忽略
三、搭建认证授权模块
3.1. 创建一个子maven项目
3.2. 引入依赖
<?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><artifactId>auth-serv</artifactId><name>auth-serv</name><parent><groupId>com.gblfy</groupId><artifactId>eshop-parent</artifactId><version>1.0-SNAPSHOT</version></parent><dependencies><!--Lombok引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- Spring Boot JPA 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId></dependency></dependencies></project>
3.3. 增加application.yaml
spring:datasource:url: jdbc:mysql://localhost:3306/auth-servusername: rootpassword: 123456main:allow-bean-definition-overriding: trueapplication:name: auth-servcloud:nacos:discovery:server-addr: 127.0.0.1:8848
server:port: 5000
3.4. 增加数据库实体
package com.gblfy.authserv.entity;import lombok.Data;import javax.persistence.*;@Entity
@Table(name = "user")
@Data
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(name = "passwd")private String passwd;@Column(name = "user_name")private String userName;@Column(name = "user_role")private String userRole;public Integer getId() {return id;}}
3.5. 增加接口
Repository 里面只需要写一个sql,通过用户名查询用户
package com.gblfy.authserv.mapper;import com.gblfy.authserv.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;```bash
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {User queryByUserName(String userName);
}
3.6. 增加用户读取实现类
package com.gblfy.authserv.service;import com.gblfy.authserv.entity.User;
import com.gblfy.authserv.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;@Service("UserDetailServiceImpl")
public class UserDetailServiceImpl implements UserDetailsService {@Autowiredprivate UserRepository userRepository;@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {//获取本地用户User user = userRepository.queryByUserName(userName);if (user != null) {//返回oauth2的用户return new org.springframework.security.core.userdetails.User(user.getUserName(),user.getPasswd(),AuthorityUtils.createAuthorityList(user.getPasswd()));} else {throw new UsernameNotFoundException("用户[" + userName + "]不存在");}}
}
3.7. 增加授权服务配置
package com.gblfy.authserv.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
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.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;import javax.sql.DataSource;@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailService;// 认证管理器@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate DataSource dataSource;/*** access_token存储器* 这里存储在数据库,大家可以结合自己的业务场景考虑将access_token存入数据库还是redis*/@Beanpublic TokenStore tokenStore() {return new JdbcTokenStore(dataSource);}/*** 从数据库读取clientDetails相关配置* 有InMemoryClientDetailsService 和 JdbcClientDetailsService 两种方式选择*/@Beanpublic ClientDetailsService clientDetails() {return new JdbcClientDetailsService(dataSource);}/*** 注入密码加密实现器*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 认证服务器Endpoints配置*/@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//如果需要使用refresh_token模式则需要注入userDetailServiceendpoints.userDetailsService(userDetailService);endpoints.authenticationManager(this.authenticationManager);endpoints.tokenStore(tokenStore());}/*** 认证服务器相关接口权限管理*/@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients() //如果使用表单认证则需要加上.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}/*** client存储方式,此处使用jdbc存储*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(clientDetails());}
}
3.8. 增加web安全拦截
package com.gblfy.authserv.config;import com.gblfy.authserv.service.UserDetailServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Override@Bean("UserDetailServiceImpl")public UserDetailsService userDetailsService(){return new UserDetailServiceImpl();}@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}/*** 认证管理* @return 认证管理对象* @throws Exception 认证异常信息*/@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(new PasswordEncoder() {//密码加密@Overridepublic String encode(CharSequence charSequence) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();return passwordEncoder.encode(charSequence);}@Overridepublic boolean matches(CharSequence charSequence, String s) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();boolean res = passwordEncoder.matches(charSequence, s);return res;}});}/*** http安全配置* @param http http安全对象* @throws Exception http安全异常信息*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and().cors().and().csrf().disable();}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/error","/static/**","/v2/api-docs/**","/swagger-resources/**","/webjars/**","/favicon.ico");}
}
3.9. 增加controller
package com.gblfy.authserv.controller;import com.gblfy.authserv.entity.User;
import com.gblfy.authserv.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.security.Principal;@RestController
@RequestMapping("user")
public class UserController {@Autowiredpublic UserRepository userRepository;@GetMapping("getByName")public User getByName(){return userRepository.queryByUserName("ziya");}/*** 获取授权的用户信息* @param principal 当前用户* @return 授权信息*/@GetMapping("current/get")public Principal user(Principal principal){return principal;}
}
3.10. 启动类添加注解
增加Application启动类 注意@EnableResourceServer
package com.gblfy.authserv;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;@SpringBootApplication
@EnableResourceServer
@EnableDiscoveryClient
public class AuthServApplication {public static void main(String[] args) {SpringApplication.run(AuthServApplication.class, args);}}