Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add double token support for console and raft registry api #6924

Open
wants to merge 4 commits into
base: 2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public interface ConfigurationKeys {
*/
String SEATA_PREFIX = SEATA_FILE_ROOT_CONFIG + ".";

/**
* The constant SECURITY_PREFIX
*/
String SECURITY_PREFIX = "security.";

/**
* The constant SERVICE_PREFIX.
*/
Expand Down Expand Up @@ -1014,6 +1019,31 @@ public interface ConfigurationKeys {
*/
String SERVER_APPLICATION_DATA_SIZE_CHECK = SERVER_PREFIX + "applicationDataLimitCheck";

/**
* The constant SECURITY_USERNAME;
*/
String SECURITY_USERNME = SECURITY_PREFIX + "username";

/**
* The constant SECURITY_PASSWORD;
*/
String SECURITY_PASSWORD = SECURITY_PREFIX + "password";

/**
* The constant SECURITY_SECRET_KEY;
*/
String SECURITY_SECRET_KEY = SECURITY_PREFIX + "secretKey";

/**
* The constant SECURITY_ACCESS_TOKEN_VALID_TIME;
*/
String SECURITY_ACCESS_TOKEN_VALID_TIME = SECURITY_PREFIX + "accessTokenValidityInMilliseconds";

/**
* The constant SECURITY_REFRESH_TOKEN_VALID_TIME;
*/
String SECURITY_REFRESH_TOKEN_VALID_TIME = SECURITY_PREFIX + "refreshTokenValidityInMilliseconds";

/**
* The constant ROCKET_MQ_MSG_TIMEOUT
*/
Expand Down
28 changes: 23 additions & 5 deletions common/src/main/java/org/apache/seata/common/result/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,49 @@
*/
package org.apache.seata.common.result;


/**
* The Code for the response of message
*
*/
public enum Code {
/**
* response success
*/
SUCCESS("200", "ok"),
/**
* the custom error
*/
ACCESS_TOKEN_NEAR_EXPIRATION("200", "Access token is near expiration"),
/**
* server error
*/
ERROR("500", "Server error"),
/**
* the custom error
*/
LOGIN_FAILED("401", "Login failed");
LOGIN_FAILED("401", "Login failed"),
/**
* the custom error
*/
CHECK_TOKEN_FAILED("401", "Check token failed"),
/**
* the custom error
*/
ACCESS_TOKEN_EXPIRED("401", "Access token expired"),
/**
* the custom error
*/
REFRESH_TOKEN_EXPIRED("401", "Refresh token expired");

/**
* The Code.
*/
public String code;
private String code;

/**
* The Msg.
*/
public String msg;
private String msg;

private Code(String code, String msg) {
this.code = code;
Expand Down Expand Up @@ -98,4 +117,3 @@ public static String getErrorMsg(String code) {
return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@

import java.io.Serializable;


/**
* The single result
*/
public class SingleResult<T> extends Result<T> implements Serializable {
public class SingleResult<T> extends Result<T> implements Serializable {
private static final long serialVersionUID = 77612626624298767L;

/**
Expand All @@ -33,22 +32,18 @@ public class SingleResult<T> extends Result<T> implements Serializable {
public SingleResult(String code, String message) {
super(code, message);
}
public SingleResult(Code code) {
super(code.getCode(), code.getMsg());
}

public SingleResult(String code, String message, T data) {
super(code, message);
this.data = data;
}

public static <T> SingleResult<T> failure(String code, String msg) {
return new SingleResult<>(code, msg);
}

public static <T> SingleResult<T> failure(Code errorCode) {
return new SingleResult(errorCode.getCode(), errorCode.getMsg());
}

public static <T> SingleResult<T> success(T data) {
return new SingleResult<>(SUCCESS_CODE, SUCCESS_MSG,data);
public SingleResult(Code code, T data) {
super(code.getCode(), code.getMsg());
this.data = data;
}

public T getData() {
Expand Down
13 changes: 13 additions & 0 deletions console/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,19 @@
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>

<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>

<!--<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@
package org.apache.seata.console.config;

import org.apache.seata.common.util.StringUtils;
import org.apache.seata.console.filter.JwtAuthenticationTokenFilter;
import org.apache.seata.console.filter.ConsoleAuthenticationTokenFilter;
import org.apache.seata.console.security.CustomUserDetailsServiceImpl;
import org.apache.seata.console.security.JwtAuthenticationEntryPoint;
import org.apache.seata.console.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
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.WebSecurityConfigurerAdapter;
Expand All @@ -44,19 +44,29 @@
*
*/
@Configuration(proxyBeanMethods = false)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Order(2)
public class ConsoleSecurityConfig extends WebSecurityConfigurerAdapter {

/**
* The constant AUTHORIZATION_HEADER.
*/
public static final String AUTHORIZATION_HEADER = "Authorization";

/**
* The constant REFRESH_TOKEN.
*/
public static final String REFRESH_TOKEN = "refresh_token";

/**
* The constant AUTHORIZATION_TOKEN.
*/
public static final String AUTHORIZATION_TOKEN = "access_token";

/**
* The constant ACCESS_TOKEN_NEAR_EXPIRATION.
*/
public static final String ACCESS_TOKEN_NEAR_EXPIRATION = "Access_token_near_expiration";

/**
* The constant SECURITY_IGNORE_URLS_SPILT_CHAR.
*/
Expand All @@ -68,18 +78,21 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String TOKEN_PREFIX = "Bearer ";

@Autowired
@Qualifier("consoleUserDetailsService")
private CustomUserDetailsServiceImpl userDetailsService;

@Autowired
@Qualifier("consoleJwtAuthenticationEntryPoint")
private JwtAuthenticationEntryPoint unauthorizedHandler;

@Autowired
@Qualifier("consoleJwtTokenUtils")
private JwtTokenUtils tokenProvider;

@Autowired
private Environment env;

@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Bean("consoleAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
Expand All @@ -92,7 +105,7 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {

@Override
public void configure(WebSecurity web) {
String ignoreURLs = env.getProperty("seata.security.ignore.urls", "/**");
String ignoreURLs = env.getProperty("console.ignore.urls", "/**");
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
web.ignoring().antMatchers(ignoreURL.trim());
}
Expand All @@ -110,9 +123,9 @@ protected void configure(HttpSecurity http) throws Exception {
csrf.ignoringAntMatchers(csrfIgnoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR));
}
csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// don't disable csrf, jwt may be implemented based on cookies
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);
// don't disable csrf, jwt may be implemented based on cookies
http.antMatcher("/api/v1/**").addFilterBefore(new ConsoleAuthenticationTokenFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);

// disable cache
http.headers().cacheControl();
Expand All @@ -123,7 +136,6 @@ protected void configure(HttpSecurity http) throws Exception {
*
* @return the password encoder
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
*/
package org.apache.seata.console.controller;

import javax.servlet.http.HttpServletResponse;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.seata.common.result.Code;
import org.apache.seata.console.config.WebSecurityConfig;
import org.apache.seata.common.result.SingleResult;
import org.apache.seata.console.config.ConsoleSecurityConfig;
import org.apache.seata.console.security.User;
import org.apache.seata.console.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand All @@ -33,17 +34,22 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;

/**
* auth user
*
*/
@RestController
@Api(tags = "Console authentication APIs")
@RequestMapping("/api/v1/auth")
public class AuthController {
@Autowired
@Qualifier("consoleJwtTokenUtils")
private JwtTokenUtils jwtTokenUtils;

@Autowired
@Qualifier("consoleAuthenticationManager")
private AuthenticationManager authenticationManager;

/**
Expand All @@ -54,26 +60,28 @@ public class AuthController {
* @return HTTP code equal to 200 indicates that Seata is in right states. HTTP code equal to 500 indicates that
* Seata is in broken states.
*/
@ApiOperation("login and get access token and refresh token")
@PostMapping("/login")
public SingleResult<String> login(HttpServletResponse response, @RequestBody User user) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
user.getUsername(), user.getPassword());
user.getUsername(), user.getPassword());

try {
//AuthenticationManager(default ProviderManager) #authenticate check Authentication
Authentication authentication = authenticationManager.authenticate(authenticationToken);
//bind authentication to securityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
//create token
String token = jwtTokenUtils.createToken(authentication);
String accessToken = jwtTokenUtils.createAccessToken(authentication);
String refreshToken = jwtTokenUtils.createRefreshToken(authentication);

String authHeader = WebSecurityConfig.TOKEN_PREFIX + token;
String authHeader = ConsoleSecurityConfig.TOKEN_PREFIX + accessToken;
//put token into http header
response.addHeader(WebSecurityConfig.AUTHORIZATION_HEADER, authHeader);

return SingleResult.success(authHeader);
response.addHeader(ConsoleSecurityConfig.AUTHORIZATION_HEADER, authHeader);
response.addHeader(ConsoleSecurityConfig.REFRESH_TOKEN, refreshToken);
return new SingleResult<>(Code.SUCCESS, authHeader);
} catch (BadCredentialsException authentication) {
return SingleResult.failure(Code.LOGIN_FAILED);
return new SingleResult<>(Code.LOGIN_FAILED);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,24 @@
*/
package org.apache.seata.console.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.seata.common.result.Code;
import org.apache.seata.common.result.SingleResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Overview
*
*/
@RestController
@Api(tags = "Overview APIs")
@RequestMapping("/api/v1/overview")
public class OverviewController {

Expand All @@ -40,6 +42,7 @@ public class OverviewController {
*
* @return the data
*/
@ApiOperation("get data")
@GetMapping(value = "/getData")
public SingleResult<List> getData() {
List<Map<String, Object>> result = new ArrayList<>();
Expand All @@ -50,7 +53,6 @@ public SingleResult<List> getData() {
hashMap.put("id", count);
result.add(hashMap);
}

return SingleResult.success(result);
return new SingleResult<>(Code.SUCCESS, result);
}
}
Loading
Loading