Skip to content

Commit

Permalink
feat: add authentication handler
Browse files Browse the repository at this point in the history
  • Loading branch information
jettcc committed Oct 23, 2023
1 parent d49842a commit e0ed175
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.achobeta.www.oauth.config;

import com.achobeta.www.oauth.config.handler.AuthenticationFailureHandler;
import com.achobeta.www.oauth.config.handler.logout.AuthenticationLogoutSuccessHandler;
import com.achobeta.www.oauth.config.handler.AuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
Expand All @@ -9,7 +12,6 @@
import org.springframework.security.web.server.SecurityWebFilterChain;

import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
import static org.springframework.security.config.Customizer.withDefaults;

/**
* <span>
Expand Down Expand Up @@ -37,10 +39,16 @@ SecurityWebFilterChain defaultSecurityFilterChain(ServerHttpSecurity http) {
.switchIfEmpty(hasRole("DBA").check(authentication, context))
)
.anyExchange().denyAll()
).formLogin(withDefaults());
http.httpBasic();
// close CSRF
http.csrf().disable();
).formLogin(fl -> fl.authenticationSuccessHandler(new AuthenticationSuccessHandler())
.authenticationFailureHandler(new AuthenticationFailureHandler()))
.logout(logoutSpec -> logoutSpec.logoutSuccessHandler(new AuthenticationLogoutSuccessHandler()))
// .httpBasic(basicSpec -> {
// basicSpec.
// })
;


http.csrf(ServerHttpSecurity.CsrfSpec::disable);
return http.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.achobeta.www.oauth.config.handler;

import com.achobeta.www.common.util.GlobalServiceStatusCode;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import reactor.core.publisher.Mono;

import static com.achobeta.www.oauth.utils.ResponseUtil.createAccessDeniedResponse;

/**
* <span>
* handler authentication failure
* </span>
*
* @author jettcc in 2023/10/23
* @version 1.0
*/
public class AuthenticationFailureHandler implements ServerAuthenticationFailureHandler {
@Override
public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
return createAccessDeniedResponse(response, GlobalServiceStatusCode.USER_NO_PERMISSION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.achobeta.www.oauth.config.handler;

import com.achobeta.www.common.util.GlobalServiceStatusCode;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import reactor.core.publisher.Mono;

import static com.achobeta.www.oauth.utils.ResponseUtil.createAccessDeniedResponse;

/**
* <span>
* authentication success handler
* </span>
*
* @author jettcc in 2023/10/23
* @version 1.0
*/
public class AuthenticationSuccessHandler implements ServerAuthenticationSuccessHandler {
@Override
public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange,
Authentication authentication) {
ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
return createAccessDeniedResponse(response, GlobalServiceStatusCode.SYSTEM_SUCCESS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.achobeta.www.oauth.config.handler.logout;

import com.achobeta.www.common.util.GlobalServiceStatusCode;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import reactor.core.publisher.Mono;

import static com.achobeta.www.oauth.utils.ResponseUtil.createAccessDeniedResponse;
/**
* <span>
* handler logout success logic
* </span>
*
* @author jettcc in 2023/10/23
* @version 1.0
*/
public class AuthenticationLogoutSuccessHandler implements ServerLogoutSuccessHandler {
@Override
public Mono<Void> onLogoutSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
return createAccessDeniedResponse(response, GlobalServiceStatusCode.SYSTEM_SUCCESS, "logout success");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.achobeta.www.oauth.utils;

import cn.hutool.json.JSONUtil;
import com.achobeta.www.common.util.GlobalServiceStatusCode;
import com.achobeta.www.common.util.SystemJsonResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
* <span>
* authentication response util
* </span>
*
* @author jettcc in 2023/10/23
* @version 1.0
*/
public class ResponseUtil {
/**
* 构造webflux返回时的结构
*/
public static Mono<Void> createAccessDeniedResponse(ServerHttpResponse resp, GlobalServiceStatusCode code) {
return createResponse(resp, code, null);
}

public static Mono<Void> createAccessDeniedResponse(ServerHttpResponse resp, GlobalServiceStatusCode code, String msg) {
return createResponse(resp, code, msg);
}

private static Mono<Void> createResponse(ServerHttpResponse resp, GlobalServiceStatusCode code, String msg) {
resp.setStatusCode(HttpStatus.OK);
resp.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
return resp.writeWith(Mono.just(resp.bufferFactory()
.wrap(JSONUtil.toJsonStr(buildResponseMessage(code, msg))
.getBytes(StandardCharsets.UTF_8))));
}

private static SystemJsonResponse buildResponseMessage(GlobalServiceStatusCode code, String msg) {
if (code == GlobalServiceStatusCode.SYSTEM_SUCCESS) {
return SystemJsonResponse.SYSTEM_SUCCESS(msg);
}
return SystemJsonResponse.CUSTOMIZE_ERROR(code);
}
}
13 changes: 12 additions & 1 deletion achobeta-infra-oauth/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
spring:
security:
user:
name: "achobeta"
# 123123
password: "$2a$10$FzwjxqvdR0c9/ScWHnJVMeSQYU/4xazCKVrz/.3/zhps6GtYlI966"
profiles:
# debug in local, use application-local.yaml
default: local
main:
datasource:
url: jdbc:mysql://rm-wz9i5gw9n7zm8mj4hro.mysql.rds.aliyuncs.com:3306/achobeta_infra?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username:
password:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# main:
# specify the type of gateway application
# case 'reactive' : processing requests in non-blocking mode
# case 'servlet' : is blocking mode
Expand Down

0 comments on commit e0ed175

Please sign in to comment.