此为反编译代码,可能需改正
This commit is contained in:
parent
9939dfbd9f
commit
bdf1815630
|
|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?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>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.2</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>com.github</groupId>
|
||||
<artifactId>spring-oauth2-authenticator</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<description>SpringBoot整合spring-security-oauth2实现完整Oauth2</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-jwt</artifactId>
|
||||
<version>1.0.9.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>2.3.6.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.3.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.github.ealen;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@MapperScan({"com.github.ealen.domain.mapper"})
|
||||
@SpringBootApplication
|
||||
public class Oauth2AuthenticatorApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Oauth2AuthenticatorApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package com.github.ealen.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.github.ealen.domain.entity.OauthAccount;
|
||||
import com.github.ealen.domain.mapper.OauthAccountMapper;
|
||||
import com.github.ealen.domain.vo.AccountInfo;
|
||||
import com.github.ealen.domain.vo.AuthResp;
|
||||
import com.github.ealen.infra.config.OauthAccountUserDetails;
|
||||
import com.github.ealen.infra.config.OauthAccountUserDetailsService;
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnauthorizedClientException;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RequestMapping({"/user"})
|
||||
@RestController
|
||||
public class UserController {
|
||||
private final OauthAccountMapper oauthAccountMapper;
|
||||
private final OauthAccountUserDetailsService oauthAccountUserDetailsService;
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
@PostMapping
|
||||
public AuthResp addUser(@RequestBody OauthAccount account) {
|
||||
String s = this.validUser(account);
|
||||
if (s != null) {
|
||||
return new AuthResp(HttpStatus.INTERNAL_SERVER_ERROR.value(), s, new HashMap());
|
||||
} else {
|
||||
OauthAccount eA = this.checkUserExists(account);
|
||||
if (eA != null) {
|
||||
return new AuthResp(HttpStatus.OK.value(), "success", new HashMap());
|
||||
} else {
|
||||
account.setAccountNonDeleted(true);
|
||||
account.setAccountNonLocked(true);
|
||||
account.setAccountNonExpired(true);
|
||||
account.setCredentialsNonExpired(true);
|
||||
account.setCreatedTime(new Date());
|
||||
account.setUpdatedTime(new Date());
|
||||
account.setPassword((new BCryptPasswordEncoder()).encode(account.getPassword()));
|
||||
account.setClientId((String)Optional.ofNullable(account.getClientId()).orElse("ci4s"));
|
||||
this.oauthAccountMapper.insert(account);
|
||||
return new AuthResp(HttpStatus.OK.value(), "success", new HashMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
public AuthResp delUser(@RequestBody OauthAccount account) {
|
||||
LambdaQueryWrapper<OauthAccount> queryWrapper = (LambdaQueryWrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery().eq(OauthAccount::getClientId, account.getClientId())).eq(OauthAccount::getUsername, account.getUsername());
|
||||
this.oauthAccountMapper.delete(queryWrapper);
|
||||
return new AuthResp(HttpStatus.OK.value(), "success", new HashMap());
|
||||
}
|
||||
|
||||
private OauthAccount checkUserExists(OauthAccount account) {
|
||||
LambdaQueryWrapper<OauthAccount> queryWrapper = (LambdaQueryWrapper)((LambdaQueryWrapper)Wrappers.lambdaQuery().eq(OauthAccount::getClientId, account.getClientId())).eq(OauthAccount::getUsername, account.getUsername());
|
||||
OauthAccount oauthAccount = (OauthAccount)this.oauthAccountMapper.selectOne(queryWrapper);
|
||||
if (oauthAccount != null) {
|
||||
oauthAccount.setPassword((new BCryptPasswordEncoder()).encode(account.getPassword()));
|
||||
oauthAccount.setEmail(account.getEmail());
|
||||
oauthAccount.setMobile(account.getMobile());
|
||||
this.oauthAccountMapper.updateById(oauthAccount);
|
||||
return oauthAccount;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String validUser(OauthAccount account) {
|
||||
if (!StringUtils.hasLength(account.getUsername())) {
|
||||
return "用户名不能为空";
|
||||
} else {
|
||||
return !StringUtils.hasLength(account.getPassword()) ? "密码不能为空" : null;
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping({"/info"})
|
||||
public AuthResp getUserInfo(@RequestHeader("Authorization") String authorizationHeader) {
|
||||
try {
|
||||
String accessToken = authorizationHeader.substring("Bearer ".length());
|
||||
String username = this.getUsernameFromToken(accessToken);
|
||||
OauthAccountUserDetails userDetails = (OauthAccountUserDetails)this.oauthAccountUserDetailsService.loadUserByUsername(username);
|
||||
OauthAccount oauthAccount = userDetails.getOauthAccount();
|
||||
oauthAccount.setPassword((String)null);
|
||||
return new AuthResp(HttpStatus.OK.value(), "success", oauthAccount);
|
||||
} catch (Exception var6) {
|
||||
return new AuthResp(HttpStatus.UNAUTHORIZED.value(), "无效的accessToken", new HashMap());
|
||||
}
|
||||
}
|
||||
|
||||
private String getUsernameFromToken(String accessToken) {
|
||||
OAuth2AccessToken oAuth2AccessToken = this.tokenStore.readAccessToken(accessToken);
|
||||
if (oAuth2AccessToken != null) {
|
||||
AccountInfo accountInfo = (AccountInfo)oAuth2AccessToken.getAdditionalInformation().get("account_info");
|
||||
return accountInfo.getUsername();
|
||||
} else {
|
||||
throw new UnauthorizedClientException("无效的accessToken");
|
||||
}
|
||||
}
|
||||
|
||||
public UserController(final OauthAccountMapper oauthAccountMapper, final OauthAccountUserDetailsService oauthAccountUserDetailsService, final TokenStore tokenStore) {
|
||||
this.oauthAccountMapper = oauthAccountMapper;
|
||||
this.oauthAccountUserDetailsService = oauthAccountUserDetailsService;
|
||||
this.tokenStore = tokenStore;
|
||||
}
|
||||
|
||||
// $FF: synthetic method
|
||||
private static Object $deserializeLambda$(SerializedLambda lambda) {
|
||||
switch (lambda.getImplMethodName()) {
|
||||
case "getClientId":
|
||||
if (lambda.getImplMethodKind() == 5 && lambda.getFunctionalInterfaceClass().equals("com/baomidou/mybatisplus/core/toolkit/support/SFunction") && lambda.getFunctionalInterfaceMethodName().equals("apply") && lambda.getFunctionalInterfaceMethodSignature().equals("(Ljava/lang/Object;)Ljava/lang/Object;") && lambda.getImplClass().equals("com/github/ealen/domain/entity/OauthAccount") && lambda.getImplMethodSignature().equals("()Ljava/lang/String;")) {
|
||||
return OauthAccount::getClientId;
|
||||
}
|
||||
|
||||
if (lambda.getImplMethodKind() == 5 && lambda.getFunctionalInterfaceClass().equals("com/baomidou/mybatisplus/core/toolkit/support/SFunction") && lambda.getFunctionalInterfaceMethodName().equals("apply") && lambda.getFunctionalInterfaceMethodSignature().equals("(Ljava/lang/Object;)Ljava/lang/Object;") && lambda.getImplClass().equals("com/github/ealen/domain/entity/OauthAccount") && lambda.getImplMethodSignature().equals("()Ljava/lang/String;")) {
|
||||
return OauthAccount::getClientId;
|
||||
}
|
||||
break;
|
||||
case "getUsername":
|
||||
if (lambda.getImplMethodKind() == 5 && lambda.getFunctionalInterfaceClass().equals("com/baomidou/mybatisplus/core/toolkit/support/SFunction") && lambda.getFunctionalInterfaceMethodName().equals("apply") && lambda.getFunctionalInterfaceMethodSignature().equals("(Ljava/lang/Object;)Ljava/lang/Object;") && lambda.getImplClass().equals("com/github/ealen/domain/entity/OauthAccount") && lambda.getImplMethodSignature().equals("()Ljava/lang/String;")) {
|
||||
return OauthAccount::getUsername;
|
||||
}
|
||||
|
||||
if (lambda.getImplMethodKind() == 5 && lambda.getFunctionalInterfaceClass().equals("com/baomidou/mybatisplus/core/toolkit/support/SFunction") && lambda.getFunctionalInterfaceMethodName().equals("apply") && lambda.getFunctionalInterfaceMethodSignature().equals("(Ljava/lang/Object;)Ljava/lang/Object;") && lambda.getImplClass().equals("com/github/ealen/domain/entity/OauthAccount") && lambda.getImplMethodSignature().equals("()Ljava/lang/String;")) {
|
||||
return OauthAccount::getUsername;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid lambda deserialization");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
package com.github.ealen.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@TableName("oauth_account")
|
||||
public class OauthAccount implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@TableId(
|
||||
type = IdType.AUTO
|
||||
)
|
||||
private Long id;
|
||||
@TableField("client_id")
|
||||
private String clientId;
|
||||
@TableField("username")
|
||||
private String username;
|
||||
@TableField("password")
|
||||
private String password;
|
||||
@TableField("mobile")
|
||||
private String mobile;
|
||||
@TableField("email")
|
||||
private String email;
|
||||
@TableField("enabled")
|
||||
private Boolean enabled;
|
||||
@TableField("account_non_expired")
|
||||
private Boolean accountNonExpired;
|
||||
@TableField("account_non_locked")
|
||||
private Boolean accountNonLocked;
|
||||
@TableField("credentials_non_expired")
|
||||
private Boolean credentialsNonExpired;
|
||||
@TableField("account_non_deleted")
|
||||
private Boolean accountNonDeleted;
|
||||
@TableField("created_time")
|
||||
private Date createdTime;
|
||||
@TableField("updated_time")
|
||||
private Date updatedTime;
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return this.mobile;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return this.email;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public Boolean getAccountNonExpired() {
|
||||
return this.accountNonExpired;
|
||||
}
|
||||
|
||||
public Boolean getAccountNonLocked() {
|
||||
return this.accountNonLocked;
|
||||
}
|
||||
|
||||
public Boolean getCredentialsNonExpired() {
|
||||
return this.credentialsNonExpired;
|
||||
}
|
||||
|
||||
public Boolean getAccountNonDeleted() {
|
||||
return this.accountNonDeleted;
|
||||
}
|
||||
|
||||
public Date getCreatedTime() {
|
||||
return this.createdTime;
|
||||
}
|
||||
|
||||
public Date getUpdatedTime() {
|
||||
return this.updatedTime;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setClientId(final String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public void setUsername(final String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setPassword(final String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void setMobile(final String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public void setEnabled(final Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setAccountNonExpired(final Boolean accountNonExpired) {
|
||||
this.accountNonExpired = accountNonExpired;
|
||||
}
|
||||
|
||||
public void setAccountNonLocked(final Boolean accountNonLocked) {
|
||||
this.accountNonLocked = accountNonLocked;
|
||||
}
|
||||
|
||||
public void setCredentialsNonExpired(final Boolean credentialsNonExpired) {
|
||||
this.credentialsNonExpired = credentialsNonExpired;
|
||||
}
|
||||
|
||||
public void setAccountNonDeleted(final Boolean accountNonDeleted) {
|
||||
this.accountNonDeleted = accountNonDeleted;
|
||||
}
|
||||
|
||||
public void setCreatedTime(final Date createdTime) {
|
||||
this.createdTime = createdTime;
|
||||
}
|
||||
|
||||
public void setUpdatedTime(final Date updatedTime) {
|
||||
this.updatedTime = updatedTime;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
} else if (!(o instanceof OauthAccount)) {
|
||||
return false;
|
||||
} else {
|
||||
OauthAccount other = (OauthAccount)o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
} else {
|
||||
Object this$id = this.getId();
|
||||
Object other$id = other.getId();
|
||||
if (this$id == null) {
|
||||
if (other$id != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$id.equals(other$id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$enabled = this.getEnabled();
|
||||
Object other$enabled = other.getEnabled();
|
||||
if (this$enabled == null) {
|
||||
if (other$enabled != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$enabled.equals(other$enabled)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$accountNonExpired = this.getAccountNonExpired();
|
||||
Object other$accountNonExpired = other.getAccountNonExpired();
|
||||
if (this$accountNonExpired == null) {
|
||||
if (other$accountNonExpired != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$accountNonExpired.equals(other$accountNonExpired)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$accountNonLocked = this.getAccountNonLocked();
|
||||
Object other$accountNonLocked = other.getAccountNonLocked();
|
||||
if (this$accountNonLocked == null) {
|
||||
if (other$accountNonLocked != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$accountNonLocked.equals(other$accountNonLocked)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$credentialsNonExpired = this.getCredentialsNonExpired();
|
||||
Object other$credentialsNonExpired = other.getCredentialsNonExpired();
|
||||
if (this$credentialsNonExpired == null) {
|
||||
if (other$credentialsNonExpired != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$credentialsNonExpired.equals(other$credentialsNonExpired)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$accountNonDeleted = this.getAccountNonDeleted();
|
||||
Object other$accountNonDeleted = other.getAccountNonDeleted();
|
||||
if (this$accountNonDeleted == null) {
|
||||
if (other$accountNonDeleted != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$accountNonDeleted.equals(other$accountNonDeleted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$clientId = this.getClientId();
|
||||
Object other$clientId = other.getClientId();
|
||||
if (this$clientId == null) {
|
||||
if (other$clientId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$clientId.equals(other$clientId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$username = this.getUsername();
|
||||
Object other$username = other.getUsername();
|
||||
if (this$username == null) {
|
||||
if (other$username != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$username.equals(other$username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$password = this.getPassword();
|
||||
Object other$password = other.getPassword();
|
||||
if (this$password == null) {
|
||||
if (other$password != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$password.equals(other$password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$mobile = this.getMobile();
|
||||
Object other$mobile = other.getMobile();
|
||||
if (this$mobile == null) {
|
||||
if (other$mobile != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$mobile.equals(other$mobile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$email = this.getEmail();
|
||||
Object other$email = other.getEmail();
|
||||
if (this$email == null) {
|
||||
if (other$email != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$email.equals(other$email)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$createdTime = this.getCreatedTime();
|
||||
Object other$createdTime = other.getCreatedTime();
|
||||
if (this$createdTime == null) {
|
||||
if (other$createdTime != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$createdTime.equals(other$createdTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$updatedTime = this.getUpdatedTime();
|
||||
Object other$updatedTime = other.getUpdatedTime();
|
||||
if (this$updatedTime == null) {
|
||||
if (other$updatedTime != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$updatedTime.equals(other$updatedTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof OauthAccount;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int PRIME = 59;
|
||||
int result = 1;
|
||||
Object $id = this.getId();
|
||||
result = result * 59 + ($id == null ? 43 : $id.hashCode());
|
||||
Object $enabled = this.getEnabled();
|
||||
result = result * 59 + ($enabled == null ? 43 : $enabled.hashCode());
|
||||
Object $accountNonExpired = this.getAccountNonExpired();
|
||||
result = result * 59 + ($accountNonExpired == null ? 43 : $accountNonExpired.hashCode());
|
||||
Object $accountNonLocked = this.getAccountNonLocked();
|
||||
result = result * 59 + ($accountNonLocked == null ? 43 : $accountNonLocked.hashCode());
|
||||
Object $credentialsNonExpired = this.getCredentialsNonExpired();
|
||||
result = result * 59 + ($credentialsNonExpired == null ? 43 : $credentialsNonExpired.hashCode());
|
||||
Object $accountNonDeleted = this.getAccountNonDeleted();
|
||||
result = result * 59 + ($accountNonDeleted == null ? 43 : $accountNonDeleted.hashCode());
|
||||
Object $clientId = this.getClientId();
|
||||
result = result * 59 + ($clientId == null ? 43 : $clientId.hashCode());
|
||||
Object $username = this.getUsername();
|
||||
result = result * 59 + ($username == null ? 43 : $username.hashCode());
|
||||
Object $password = this.getPassword();
|
||||
result = result * 59 + ($password == null ? 43 : $password.hashCode());
|
||||
Object $mobile = this.getMobile();
|
||||
result = result * 59 + ($mobile == null ? 43 : $mobile.hashCode());
|
||||
Object $email = this.getEmail();
|
||||
result = result * 59 + ($email == null ? 43 : $email.hashCode());
|
||||
Object $createdTime = this.getCreatedTime();
|
||||
result = result * 59 + ($createdTime == null ? 43 : $createdTime.hashCode());
|
||||
Object $updatedTime = this.getUpdatedTime();
|
||||
result = result * 59 + ($updatedTime == null ? 43 : $updatedTime.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "OauthAccount(id=" + this.getId() + ", clientId=" + this.getClientId() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ", mobile=" + this.getMobile() + ", email=" + this.getEmail() + ", enabled=" + this.getEnabled() + ", accountNonExpired=" + this.getAccountNonExpired() + ", accountNonLocked=" + this.getAccountNonLocked() + ", credentialsNonExpired=" + this.getCredentialsNonExpired() + ", accountNonDeleted=" + this.getAccountNonDeleted() + ", createdTime=" + this.getCreatedTime() + ", updatedTime=" + this.getUpdatedTime() + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.github.ealen.domain.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.github.ealen.domain.entity.OauthAccount;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface OauthAccountMapper extends BaseMapper<OauthAccount> {
|
||||
OauthAccount loadUserByUsername(@Param("clientId") String clientId, @Param("username") String username);
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
package com.github.ealen.domain.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AccountInfo implements Serializable {
|
||||
private Long id;
|
||||
private String clientId;
|
||||
private String username;
|
||||
private String mobile;
|
||||
private String email;
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return this.mobile;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return this.email;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setClientId(final String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public void setUsername(final String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setMobile(final String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
} else if (!(o instanceof AccountInfo)) {
|
||||
return false;
|
||||
} else {
|
||||
AccountInfo other = (AccountInfo)o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
} else {
|
||||
Object this$id = this.getId();
|
||||
Object other$id = other.getId();
|
||||
if (this$id == null) {
|
||||
if (other$id != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$id.equals(other$id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$clientId = this.getClientId();
|
||||
Object other$clientId = other.getClientId();
|
||||
if (this$clientId == null) {
|
||||
if (other$clientId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$clientId.equals(other$clientId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$username = this.getUsername();
|
||||
Object other$username = other.getUsername();
|
||||
if (this$username == null) {
|
||||
if (other$username != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$username.equals(other$username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$mobile = this.getMobile();
|
||||
Object other$mobile = other.getMobile();
|
||||
if (this$mobile == null) {
|
||||
if (other$mobile != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$mobile.equals(other$mobile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object this$email = this.getEmail();
|
||||
Object other$email = other.getEmail();
|
||||
if (this$email == null) {
|
||||
if (other$email != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this$email.equals(other$email)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof AccountInfo;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int PRIME = 59;
|
||||
int result = 1;
|
||||
Object $id = this.getId();
|
||||
result = result * 59 + ($id == null ? 43 : $id.hashCode());
|
||||
Object $clientId = this.getClientId();
|
||||
result = result * 59 + ($clientId == null ? 43 : $clientId.hashCode());
|
||||
Object $username = this.getUsername();
|
||||
result = result * 59 + ($username == null ? 43 : $username.hashCode());
|
||||
Object $mobile = this.getMobile();
|
||||
result = result * 59 + ($mobile == null ? 43 : $mobile.hashCode());
|
||||
Object $email = this.getEmail();
|
||||
result = result * 59 + ($email == null ? 43 : $email.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AccountInfo(id=" + this.getId() + ", clientId=" + this.getClientId() + ", username=" + this.getUsername() + ", mobile=" + this.getMobile() + ", email=" + this.getEmail() + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.github.ealen.domain.vo;
|
||||
|
||||
public class AuthResp<T> {
|
||||
private int code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
public AuthResp(int status, String message, T data) {
|
||||
this.code = status;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public AuthResp() {
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.github.ealen.infra.config;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
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.client.JdbcClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
|
||||
@Configuration
|
||||
@EnableAuthorizationServer
|
||||
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
|
||||
@Resource
|
||||
private AuthorizationServerTokenServices tokenServices;
|
||||
@Resource
|
||||
private AuthenticationManager authenticationManagerBean;
|
||||
@Resource
|
||||
private JdbcClientDetailsService jdbcClientDetailsService;
|
||||
|
||||
public void configure(AuthorizationServerSecurityConfigurer security) {
|
||||
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();
|
||||
}
|
||||
|
||||
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||
clients.withClientDetails(this.jdbcClientDetailsService);
|
||||
}
|
||||
|
||||
public void configure(AuthorizationServerEndpointsConfigurer configurer) {
|
||||
configurer.tokenServices(this.tokenServices);
|
||||
configurer.authenticationManager(this.authenticationManagerBean);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.github.ealen.infra.config;
|
||||
|
||||
import com.github.ealen.domain.entity.OauthAccount;
|
||||
import java.util.Collection;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
public class OauthAccountUserDetails implements UserDetails {
|
||||
private final OauthAccount oauthAccount;
|
||||
private final Collection<? extends GrantedAuthority> authorities;
|
||||
|
||||
public OauthAccountUserDetails(OauthAccount oauthAccount, Collection<? extends GrantedAuthority> authorities) {
|
||||
this.oauthAccount = oauthAccount;
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
public OauthAccount getOauthAccount() {
|
||||
return this.oauthAccount;
|
||||
}
|
||||
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.authorities;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.oauthAccount.getPassword();
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.oauthAccount.getUsername();
|
||||
}
|
||||
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.oauthAccount.getAccountNonExpired();
|
||||
}
|
||||
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.oauthAccount.getAccountNonLocked();
|
||||
}
|
||||
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.oauthAccount.getCredentialsNonExpired();
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.oauthAccount.getEnabled();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.github.ealen.infra.config;
|
||||
|
||||
import com.github.ealen.domain.entity.OauthAccount;
|
||||
import com.github.ealen.domain.mapper.OauthAccountMapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
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.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.common.exceptions.BadClientCredentialsException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnauthorizedClientException;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationConverter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
@Service
|
||||
public class OauthAccountUserDetailsService implements UserDetailsService {
|
||||
@Resource
|
||||
private OauthAccountMapper oauthAccountMapper;
|
||||
private final BasicAuthenticationConverter authenticationConverter = new BasicAuthenticationConverter();
|
||||
@Resource
|
||||
private JdbcClientDetailsService jdbcClientDetailsService;
|
||||
@Resource
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
public UserDetails loadUserByUsername(String username) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String clientId = null;
|
||||
OauthAccount account = this.oauthAccountMapper.loadUserByUsername(clientId, username);
|
||||
if (account != null && account.getAccountNonDeleted()) {
|
||||
List<SimpleGrantedAuthority> authorities = new ArrayList();
|
||||
return new OauthAccountUserDetails(account, authorities);
|
||||
} else {
|
||||
throw new UsernameNotFoundException("user not found");
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientIdByRequest() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
UsernamePasswordAuthenticationToken client = this.authenticationConverter.convert(request);
|
||||
if (client == null) {
|
||||
throw new UnauthorizedClientException("unauthorized client");
|
||||
} else {
|
||||
ClientDetails clientDetails = this.jdbcClientDetailsService.loadClientByClientId(client.getName());
|
||||
if (!this.passwordEncoder.matches((String)client.getCredentials(), clientDetails.getClientSecret())) {
|
||||
throw new BadClientCredentialsException();
|
||||
} else {
|
||||
return clientDetails.getClientId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package com.github.ealen.infra.config;
|
||||
|
||||
import com.github.ealen.domain.vo.AccountInfo;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
|
||||
@Configuration
|
||||
public class OauthClientAccessTokenConfig {
|
||||
private static final String SIGNING_KEY = "5371f568a45e5ab1f442c38e0932aef24447139b";
|
||||
@Resource
|
||||
private DataSource dataSource;
|
||||
|
||||
@Bean
|
||||
public JdbcClientDetailsService jdbcClientDetailsService() {
|
||||
return new JdbcClientDetailsService(this.dataSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenStore tokenStore() {
|
||||
return new JdbcTokenStore(this.dataSource);
|
||||
}
|
||||
|
||||
@Bean(
|
||||
name = {"tokenServices"}
|
||||
)
|
||||
public AuthorizationServerTokenServices tokenServices() {
|
||||
DefaultTokenServices tokenServices = new DefaultTokenServices();
|
||||
tokenServices.setClientDetailsService(this.jdbcClientDetailsService());
|
||||
tokenServices.setSupportRefreshToken(true);
|
||||
tokenServices.setReuseRefreshToken(false);
|
||||
tokenServices.setTokenStore(this.tokenStore());
|
||||
tokenServices.setTokenEnhancer(this.tokenEnhancerChain());
|
||||
return tokenServices;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenEnhancerChain tokenEnhancerChain() {
|
||||
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
|
||||
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(this.jwtAccessTokenConverter(), this.additionalInformationTokenEnhancer()));
|
||||
return tokenEnhancerChain;
|
||||
}
|
||||
|
||||
@Bean
|
||||
JwtAccessTokenConverter jwtAccessTokenConverter() {
|
||||
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
|
||||
converter.setSigningKey("5371f568a45e5ab1f442c38e0932aef24447139b");
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenEnhancer additionalInformationTokenEnhancer() {
|
||||
return (accessToken, authentication) -> {
|
||||
Map<String, Object> information = new HashMap(8);
|
||||
Authentication userAuthentication = authentication.getUserAuthentication();
|
||||
if (userAuthentication instanceof UsernamePasswordAuthenticationToken) {
|
||||
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken)userAuthentication;
|
||||
Object principal = token.getPrincipal();
|
||||
if (principal instanceof OauthAccountUserDetails) {
|
||||
OauthAccountUserDetails userDetails = (OauthAccountUserDetails)token.getPrincipal();
|
||||
AccountInfo accountInfo = new AccountInfo();
|
||||
BeanUtils.copyProperties(userDetails.getOauthAccount(), accountInfo);
|
||||
information.put("account_info", accountInfo);
|
||||
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(information);
|
||||
}
|
||||
}
|
||||
|
||||
return accessToken;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package com.github.ealen.infra.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.ealen.domain.vo.AuthResp;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
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.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.web.cors.CorsUtils;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Lazy
|
||||
@Resource
|
||||
private OauthAccountUserDetailsService oauthAccountUserDetailsService;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
RequestCache requestCache = new HttpSessionRequestCache();
|
||||
protected static final String[] PERMIT_ALL_URL = new String[]{"/oauth/**", "/user/**", "/actuator/**", "/error", "/open/api"};
|
||||
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
((HttpSecurity)((FormLoginConfigurer)((FormLoginConfigurer)((FormLoginConfigurer)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((HttpSecurity)((HttpSecurity)http.cors().and()).csrf().disable()).authorizeRequests().antMatchers(HttpMethod.OPTIONS)).permitAll().requestMatchers(new RequestMatcher[]{CorsUtils::isPreFlightRequest})).permitAll().antMatchers(PERMIT_ALL_URL)).permitAll().and()).formLogin().loginPage("/").loginProcessingUrl("/login")).usernameParameter("username").passwordParameter("password").successHandler(this.authenticationSuccessHandler())).failureHandler(this.authenticationFailureHandler())).and()).logout().invalidateHttpSession(true).clearAuthentication(true).deleteCookies(new String[]{"JSESSIONID"});
|
||||
http.headers().frameOptions().disable();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||
return (httpServletRequest, httpServletResponse, authentication) -> {
|
||||
Object principal = authentication.getPrincipal();
|
||||
OauthAccountUserDetails o = (OauthAccountUserDetails)principal;
|
||||
httpServletResponse.setContentType("application/json");
|
||||
Map<String, Object> map = new HashMap();
|
||||
map.put("client_id", o.getOauthAccount().getClientId());
|
||||
map.put("response_type", "code");
|
||||
map.put("grant_type", "authorization_code");
|
||||
SavedRequest savedRequest = this.requestCache.getRequest(httpServletRequest, httpServletResponse);
|
||||
if (savedRequest != null) {
|
||||
String[] clientIds = savedRequest.getParameterValues("client_id");
|
||||
if (clientIds != null && clientIds.length > 0) {
|
||||
map.put("client_id", clientIds[0]);
|
||||
}
|
||||
}
|
||||
|
||||
AuthResp resp = new AuthResp(HttpStatus.OK.value(), "login success", map);
|
||||
httpServletResponse.getWriter().write(this.objectMapper.writeValueAsString(resp));
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LogoutSuccessHandler logoutSuccessHandler() {
|
||||
return (httpServletRequest, httpServletResponse, authentication) -> {
|
||||
httpServletResponse.setContentType("application/json");
|
||||
AuthResp resp = new AuthResp(HttpStatus.OK.value(), "logout success", new HashMap());
|
||||
httpServletResponse.getWriter().write(this.objectMapper.writeValueAsString(resp));
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationFailureHandler authenticationFailureHandler() {
|
||||
return (httpServletRequest, httpServletResponse, e) -> {
|
||||
httpServletResponse.setContentType("application/json");
|
||||
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
AuthResp resp = new AuthResp(HttpStatus.UNAUTHORIZED.value(), e.getMessage(), new HashMap());
|
||||
httpServletResponse.getWriter().write(this.objectMapper.writeValueAsString(resp));
|
||||
};
|
||||
}
|
||||
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(this.oauthAccountUserDetailsService).passwordEncoder(this.passwordEncoder());
|
||||
auth.eraseCredentials(true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
spring:
|
||||
application:
|
||||
name: oauth2-authenticator
|
||||
datasource:
|
||||
url: jdbc:mysql://${DB_URL:172.20.32.106:3306}/authorization_center?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: ${DB_USERNAME:root}
|
||||
password: ${DB_PASSWORD:123456}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
security:
|
||||
csrf:
|
||||
cookie:
|
||||
same-site: "None"
|
||||
secure: true
|
||||
|
||||
mybatis-plus:
|
||||
# 扫码 *Mapper.xml 路径
|
||||
mapper-locations: classpath:/mapper/**.xml
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
INSERT INTO `oauth_account`(id, client_id, username, password, mobile, email, enabled, account_non_expired,
|
||||
credentials_non_expired, account_non_locked, account_non_deleted)
|
||||
VALUES (1, 'ABC', 'ealenxie', '$2a$10$IzjmkjegAMXtycRnGyBZl.ZMwNxoUhCCCn8/lwlLswdMQ6TcvU3P2', '1232378743',
|
||||
'abc@123.com', 1, 1, 1, 1, 1);
|
||||
INSERT INTO `oauth_client_details`(`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`,
|
||||
`web_server_redirect_uri`, `authorities`, `access_token_validity`,
|
||||
`refresh_token_validity`, `additional_information`, `autoapprove`)
|
||||
VALUES ('ABC', 'demo-app', '$2a$10$LaY9MNGFaInbMTx1nhaVXuGwyqMmNExCYoGZK/FJL2G91SIfVnXp2', 'read,write',
|
||||
'client_credentials,authorization_code,password,refresh_token,implicit', 'http://www.baidu.com', 'user', 7199,
|
||||
2592000, NULL, 'true');
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
SET NAMES utf8mb4;
|
||||
SET
|
||||
FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
/* OAUTH2.0 系统表 */
|
||||
drop table if exists oauth_access_token;
|
||||
|
||||
drop table if exists oauth_approvals;
|
||||
|
||||
drop table if exists oauth_client_details;
|
||||
|
||||
drop table if exists oauth_client_token;
|
||||
|
||||
drop table if exists oauth_code;
|
||||
|
||||
drop table if exists oauth_refresh_token;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_access_token */
|
||||
/*==============================================================*/
|
||||
create table oauth_access_token
|
||||
(
|
||||
token_id varchar(255),
|
||||
token blob,
|
||||
authentication_id varchar(255) not null,
|
||||
user_name varchar(255),
|
||||
client_id varchar(255),
|
||||
authentication blob,
|
||||
refresh_token varchar(255),
|
||||
primary key (authentication_id)
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_approvals */
|
||||
/*==============================================================*/
|
||||
create table oauth_approvals
|
||||
(
|
||||
userId varchar(255),
|
||||
clientId varchar(255),
|
||||
scope varchar(255),
|
||||
status varchar(10),
|
||||
expiresAt TIMESTAMP DEFAULT '2030-01-01 00:00:00',
|
||||
lastModifiedAt TIMESTAMP DEFAULT '2030-01-01 00:00:00'
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_client_details */
|
||||
/*==============================================================*/
|
||||
create table oauth_client_details
|
||||
(
|
||||
client_id varchar(255) not null,
|
||||
resource_ids varchar(255),
|
||||
client_secret varchar(255),
|
||||
scope varchar(255),
|
||||
authorized_grant_types varchar(255),
|
||||
web_server_redirect_uri varchar(255),
|
||||
authorities varchar(255),
|
||||
access_token_validity INTEGER,
|
||||
refresh_token_validity INTEGER,
|
||||
additional_information varchar(4096),
|
||||
autoapprove varchar(255),
|
||||
primary key (client_id)
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_client_token */
|
||||
/*==============================================================*/
|
||||
create table oauth_client_token
|
||||
(
|
||||
token_id varchar(255),
|
||||
token blob,
|
||||
authentication_id varchar(255) not null,
|
||||
user_name varchar(255),
|
||||
client_id varchar(255),
|
||||
primary key (authentication_id)
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_code */
|
||||
/*==============================================================*/
|
||||
create table oauth_code
|
||||
(
|
||||
code varchar(255),
|
||||
authentication blob
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_refresh_token */
|
||||
/*==============================================================*/
|
||||
create table oauth_refresh_token
|
||||
(
|
||||
token_id varchar(255),
|
||||
token blob,
|
||||
authentication blob
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- 自定义认证中心账号表
|
||||
drop table if exists oauth_account;
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: oauth_account */
|
||||
/*==============================================================*/
|
||||
create table oauth_account
|
||||
(
|
||||
id int(11) not null auto_increment comment '账号ID',
|
||||
client_id varchar(50) not null comment '客户端ID',
|
||||
username varchar(50) not null comment '用户名',
|
||||
password varchar(200) comment '密码',
|
||||
mobile varchar(13) comment '手机号',
|
||||
email varchar(100) comment '邮箱',
|
||||
enabled tinyint(1) comment '账号可用',
|
||||
account_non_expired tinyint(1) default 1 comment '账号未过期',
|
||||
credentials_non_expired tinyint(1) default 1 comment '密码未过期',
|
||||
account_non_locked tinyint(1) default 1 comment '账号未锁定',
|
||||
account_non_deleted tinyint(1) default 1 comment '账号未删除',
|
||||
created_time datetime default CURRENT_TIMESTAMP comment '创建时间',
|
||||
updated_time datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
alter table `oauth_account`
|
||||
add index `user_idx` (`client_id`, `username`, `password`) using btree;
|
||||
alter table oauth_account
|
||||
comment '自定义认证中心账号表';
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.github.ealen.domain.mapper.OauthAccountMapper">
|
||||
|
||||
|
||||
<select id="loadUserByUsername" resultType="com.github.ealen.domain.entity.OauthAccount">
|
||||
select *
|
||||
from oauth_account
|
||||
where
|
||||
account_non_deleted = true and username = #{username}
|
||||
<if test="clientId != null">
|
||||
and client_id = #{clientId}
|
||||
</if>
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<link rel="stylesheet" href="/umi.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="/umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[717],{98303:function(f,o,r){r.r(o),r.d(o,{default:function(){return d}});var l=r(93578),_={navs:"navs___X754f"},t=r(85893);function d(){return(0,t.jsx)("div",{className:_.navs,children:(0,t.jsx)(l.j3,{})})}},75251:function(f,o,r){var l;var _=r(67294),t=Symbol.for("react.element"),d=Symbol.for("react.fragment"),v=Object.prototype.hasOwnProperty,y=_.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,m={key:!0,ref:!0,__self:!0,__source:!0};function p(u,e,a){var n,s={},i=null,c=null;a!==void 0&&(i=""+a),e.key!==void 0&&(i=""+e.key),e.ref!==void 0&&(c=e.ref);for(n in e)v.call(e,n)&&!m.hasOwnProperty(n)&&(s[n]=e[n]);if(u&&u.defaultProps)for(n in e=u.defaultProps,e)s[n]===void 0&&(s[n]=e[n]);return{$$typeof:t,type:u,key:i,ref:c,props:s,_owner:y.current}}l=d,o.jsx=p,o.jsxs=p},85893:function(f,o,r){f.exports=r(75251)}}]);
|
||||
|
|
@ -0,0 +1 @@
|
|||
.navs___X754f{height:100%;width:100%}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
.user-login___iDZg_{display:flex;height:100vh;background-color:#fff}.user-login__left___jcyGW{position:relative;width:43%;height:100%;padding-top:56px;background:linear-gradient(180deg,#e2ecff,#f6fafe)}.user-login__left__top___ux8Tk{display:flex;align-items:center;margin-left:50px;color:#1d1d20;font-size:30px;font-family:Alibaba}.user-login__left__title___YvOMy{position:relative;display:flex;justify-content:center;margin-top:70px;margin-left:85px;color:#111;font-weight:500;font-size:45px;font-family:Alibaba}.user-login__left__title__img___RIOsC{position:relative;top:-10px;width:85px;height:47px}.user-login__left__message___Yapjg{display:flex;justify-content:center;margin-top:18px;color:#606b7a;font-size:26px;font-family:Alibaba}.user-login__left__bottom-img___RgDs4{width:100%;height:calc(100% - 300px);margin-top:50px;object-fit:contain}.user-login__right___jGIZH{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;width:57%;height:100%;background:#fff}.user-login__right__title___dtlvS{margin-bottom:24px;color:#1664ff;font-size:36px;font-family:Alibaba}.user-login__right__content___PYUmx{width:640px;padding:60px 60px 45px;background-color:#fff;border-radius:10px;box-shadow:0 3px 20px #99999929}.user-login__right__content__title___Do7oS{margin-bottom:40px;color:#1d1d20;font-size:22px;font-family:Alibaba}.user-login__right__content__form__captcha___nCPGE{width:170px;height:66px;padding-left:22px;cursor:pointer}.user-login__right__content__form___jB0B2 .ant-form-item{margin-bottom:32px}.user-login__right__content__form___jB0B2 .ant-form-item:last-child{margin-bottom:0}.user-login__right__content__form___jB0B2 .ant-input-affix-wrapper{padding:10px 11px;color:#1d1d20;font-size:18px!important;background-color:#fff;border:1px solid #caced8;border-radius:13px}.user-login__right__content__form___jB0B2 .ant-input-affix-wrapper .ant-input{height:44px;font-size:18px!important}.user-login__right__content__form___jB0B2 .ant-btn{width:100%;height:76px;font-size:20px;border-radius:38px}.user-login___iDZg_ input{font-size:18px!important}.user-login___iDZg_ input:-webkit-autofill{font-size:18px!important;-webkit-transition:background-color 5000s ease-in-out 0s;transition:background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#1d1d20!important}.user-login___iDZg_ input:-webkit-autofill:first-line{font-size:18px!important}.login-input-prefix____6Op6{display:flex;align-items:center;height:44px;margin-right:15px}.login-input-prefix__icon___tnwfo{width:24px;height:26px;margin-right:18px;margin-left:14px}.login-input-prefix__line___aVJIE{width:1px;height:30px;background-color:#caced8}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 783 KiB |
|
|
@ -0,0 +1 @@
|
|||
html,body,#root{min-width:1440px;height:100%;margin:0;padding:0;overflow-y:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue