添加oauth2单点登录功能

This commit is contained in:
macro
2019-10-25 17:08:42 +08:00
parent ffa4ce5450
commit 8c22ba0f2f
18 changed files with 508 additions and 86 deletions

31
mall-oauth/.gitignore vendored Normal file
View File

@@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

60
mall-oauth/pom.xml Normal file
View File

@@ -0,0 +1,60 @@
<?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>
<groupId>com.macro.mall</groupId>
<artifactId>mall-oauth</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mall-oauth</name>
<description>mall-oauth project for mall</description>
<parent>
<groupId>com.macro.mall</groupId>
<artifactId>mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.macro.mall</groupId>
<artifactId>mall-mbg</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.macro.mall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MallOauthApplication {
public static void main(String[] args) {
SpringApplication.run(MallOauthApplication.class, args);
}
}

View File

@@ -0,0 +1,69 @@
package com.macro.mall.config;
import com.macro.mall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
/**
* 认证服务器配置
* Created by macro on 2019/9/30.
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserService userService;
@Autowired
@Qualifier("jwtTokenStore")
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
/**
* 使用密码模式需要配置
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userService)
.tokenStore(tokenStore) //配置令牌存储策略
.accessTokenConverter(jwtAccessTokenConverter);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("mall-portal")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(864000)
.redirectUris("http://localhost:8201/mall-portal/login") //单点登录时配置
.autoApprove(true) //自动授权配置
.scopes("all")
.authorizedGrantTypes("authorization_code","password","refresh_token");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("isAuthenticated()"); // 获取密钥需要身份认证,使用单点登录时必须配置
}
}

View File

@@ -0,0 +1,27 @@
package com.macro.mall.config;
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.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
/**
* 使用Jwt存储token的配置
* Created by macro on 2019/10/8.
*/
@Configuration
public class JwtTokenStoreConfig {
@Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("test_key");//配置JWT使用的秘钥
return accessTokenConverter;
}
}

View File

@@ -0,0 +1,15 @@
package com.macro.mall.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MyBatis配置类
* Created by macro on 2019/4/8.
*/
@Configuration
@EnableTransactionManagement
@MapperScan({"com.macro.mall.mapper"})
public class MyBatisConfig {
}

View File

@@ -0,0 +1,25 @@
package com.macro.mall.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
* 资源服务器配置
* Created by macro on 2019/9/30.
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/user/**");
}
}

View File

@@ -0,0 +1,44 @@
package com.macro.mall.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* SpringSecurity配置
* Created by macro on 2019/10/8.
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/oauth/**", "/login/**", "/logout/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll();
}
}

View File

@@ -0,0 +1,29 @@
package com.macro.mall.controller;
import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.Jwts;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
/**
* Created by macro on 2019/9/30.
*/
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/getCurrentUser")
public Object getCurrentUser(Authentication authentication, HttpServletRequest request) {
String header = request.getHeader("Authorization");
String token = StrUtil.subAfter(header, "bearer ", false);
return Jwts.parser()
.setSigningKey("test_key".getBytes(StandardCharsets.UTF_8))
.parseClaimsJws(token)
.getBody();
}
}

View File

@@ -0,0 +1,61 @@
package com.macro.mall.domain;
import com.macro.mall.model.UmsMember;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays;
import java.util.Collection;
/**
* 会员详情封装
* Created by macro on 2018/8/3.
*/
public class MemberDetails implements UserDetails {
private UmsMember umsMember;
public MemberDetails(UmsMember umsMember) {
this.umsMember = umsMember;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限
return Arrays.asList(new SimpleGrantedAuthority("TEST"));
}
@Override
public String getPassword() {
return umsMember.getPassword();
}
@Override
public String getUsername() {
return umsMember.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return umsMember.getStatus()==1;
}
public UmsMember getUmsMember() {
return umsMember;
}
}

View File

@@ -0,0 +1,34 @@
package com.macro.mall.service;
import com.macro.mall.domain.MemberDetails;
import com.macro.mall.mapper.UmsMemberMapper;
import com.macro.mall.model.UmsMember;
import com.macro.mall.model.UmsMemberExample;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
* Created by macro on 2019/9/30.
*/
@Service
public class UserService implements UserDetailsService {
@Autowired
private UmsMemberMapper memberMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UmsMemberExample example = new UmsMemberExample();
example.createCriteria().andUsernameEqualTo(username);
List<UmsMember> memberList = memberMapper.selectByExample(example);
if (!CollectionUtils.isEmpty(memberList)) {
return new MemberDetails(memberList.get(0));
}
throw new UsernameNotFoundException("用户名或密码错误");
}
}

View File

@@ -0,0 +1,35 @@
server:
port: 9401
spring:
application:
name: mall-oauth
datasource:
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
druid:
initial-size: 5 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
web-stat-filter:
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
stat-view-servlet: #访问监控网页的登录用户名和密码
login-username: druid
login-password: druid
mybatis:
mapper-locations:
- classpath:dao/*.xml
- classpath*:com/**/mapper/*.xml
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/

View File

@@ -0,0 +1,16 @@
package com.macro.mall;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MallOauthApplicationTests {
@Test
public void contextLoads() {
}
}