Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the development and principle of single sign-on SSO for JWT

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "what is the development and principle of JWT single sign-on SSO". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

> when learning Spring Cloud,    always has little knowledge of oauth related to authorization service, so he decides to first study and sort through the permissions such as Spring Security, Spring Security Oauth3, authentication-related content, principles and design. This series of articles is written to strengthen the impression and understanding in the process of learning. Please let me know if there is any infringement.

> Project environment: >-JDK1.8 >-Spring boot 2.x >-Spring Security 5.x

   single sign-on (Single Sign On), referred to as SSO for short, is one of the popular solutions for enterprise business integration. SSO is defined as that in multiple application systems, users only need to log in once to access all the applications that trust each other. Single sign-on is essentially the use of OAuth3, so its development depends on authorization authentication services, if you are not clear, you can see my previous article.

First, single sign-on Demo development

   knows from the definition of single sign-on that we need to create a new application, and I call it security-sso-client. The next development is on this application.

I. Maven dependence

   mainly depends on spring-boot-starter-security, spring-security-oauth3-autoconfigure and spring-security-oauth3. Among them, spring-security-oauth3-autoconfigure is only available in Spring Boot 2.x.

Org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-data-redis org.springframework.security.oauth.boot spring-security-oauth3-autoconfigure org.springframework.security.oauth spring-security-oauth3 2.1.7.RELEASE org.springframework.security.oauth spring-security-oauth3 2.3.5.RELEASE II. Single point configuration @ EnableOAuth3Sso

The introduction of the basic configuration of a single point of    relies on @ EnableOAuth3Sso, and @ EnableOAuth3Sso in Spring Boot 2.x and above is in the spring-security-oauth3-autoconfigure dependency. I have a simple configuration here:

@ Configuration@EnableOAuth3Ssopublic class ClientSecurityConfig extends WebSecurityConfigurerAdapter {@ Override public void configure (HttpSecurity http) throws Exception {http.authorizeRequests () .antMatch ("/", "/ error", "/ login") .permitAll () .anyRequest () .csrf () .disable ();}}

   will redirect to / error because there may be some problems during the single point, so we set / error to have no permission to access.

Third, test interface and page test interface @ RestController@Slf4jpublic class TestController {@ GetMapping ("/ client/ {clientId}") public String getClient (@ PathVariable String clientId) {return clientId;}} test page OSS-client OSS-client jump to OSS-client-1 jump to OSS-client- 2 IV, single point profile configuration authorization information

   since we are going to test a single point of multiple applications, we need at least 2 single point clients, which are implemented through the multi-environment configuration of Spring Boot.

Application.yml configuration

   We all know that a single point of implementation is essentially the authenticator mode of Oauth3, so we need to configure the address information to access the authorization server, including:

Security.oauth3.client.user-authorization-uri = / oauth/authorize request authentication address, that is, get the code code

Security.oauth3.client.access-token-uri = / address of the oauth/token request token

Security.oauth3.resource.jwt.key-uri = / oauth/token_key address of the key required for parsing the jwt token. When the service starts, the authorization service is called to obtain the jwt key. Therefore, make sure that the authorization service is normal.

Security.oauth3.client.client-id = client1 clientId information

Security.oauth3.client.client-secret = 123456 clientSecret information

There are several configurations that need to be explained briefly:

The security.oauth3.sso.login-path=/login OAuth3 license server triggers the redirect to the client. The default is / login, which is the same as the path after the callback address (domain name) of the authorization server.

Server.servlet.session.cookie.name = OAUTH2CLIENTSESSION solves the problems existing in stand-alone development, and its configuration can be ignored if it is not a stand-alone development.

Auth-server: http://localhost:9090 # authorization service address

Security: oauth3: client: user-authorization-uri: ${auth-server} / oauth/authorize # address for requesting authentication access-token-uri: ${auth-server} / oauth/token # address for requesting tokens resource: jwt: key-uri: ${auth-server} / oauth/token_key # address for keys needed to resolve jwt tokens. When the service starts, the authorization service is called to obtain jwt key. So make sure that the authorization service sso: login-path: / login # points to the path to the login page, that is, the OAuth3 authorization server triggers the redirection to the client. The default is / login.

Server: servlet: session: cookie: name: OAUTH2CLIENTSESSION # solve the Possible CSRF detected-state parameter was required but no state could be found problem spring: profiles: active: client1

# application-client1.yml configuration    application-client2 is the same as application-client1, except that the port number and client information are different, so it will not be repeated here.

Server: port: 8091

Security: oauth3: client: client-id: client1 client-secret: 123456

# 5. The effect of single point test    is as follows:! [https://cache.yisu.com/upload/information/20210524/347/787917.jpg](https://cache.yisu.com/upload/information/20210524/347/787917.jpg)    from the effect diagram, we can find that when we first visited the interface of client2, we jumped to the login interface of authorization service, and successfully jumped back to the test interface of client2 after logging in. It also shows the return value of the interface. At this time, when we visit the test interface of client1, we directly return the return value of the interface. This is the effect of single point landing. Students with strong curiosity will ask in their hearts: how is it achieved? So then let's unveil it. # 2. Analyze the principle of single sign-on # 1. @ EnableOAuth3Sso    We all know that @ EnableOAuth3Sso is the core configuration annotation for single sign-on, so let's take a look at the source code of @ EnableOAuth3Sso:

Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented @ EnableOAuth3Client @ EnableConfigurationProperties (OAuth3SsoProperties.class) @ Import ({OAuth3SsoDefaultConfiguration.class, OAuth3SsoCustomConfiguration.class, ResourceServerTokenServicesConfiguration.class}) public @ interface EnableOAuth3Sso {

}

In   , we focus on the references of four configuration files: the core configuration of ResourceServerTokenServicesConfiguration, OAuth3SsoDefaultConfiguration, OAuth3SsoProperties and @ EnableOAuth3Client:- OAuth3SsoDefaultConfiguration single sign-on, the internal creation of SsoSecurityConfigurer objects, and the internal configuration of * * OAuth3ClientAuthenticationProcessingFilter**, which is one of the core filters of single sign-on. -ResourceServerTokenServicesConfiguration internally reads the information we configured in yml-OAuth3SsoProperties configures the callback address url, which is matched by security.oauth3.sso.login-path=/login-@ EnableOAuth3Client indicates the single point client, which is mainly configured with * * OAuth3ClientContextFilter**, one of the core single login filters # 2. The OAuth3ClientContextFilter    OAuth3ClientContextFilter filter is similar to ExceptionTranslationFilter and does not do any filtering. Just make a redirect handle when an exception occurs in chain.doFilter (). But don't underestimate this redirect process, which is the first step in achieving single sign-on. Remember when you first jumped to the login page of the authorization server? And this function is implemented by OAuth3ClientContextFilter. Let's take a look at the source code:

Public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; request.setAttribute (CURRENT_URI, calculateCurrentUri (request)); / / 1. Record the current address (currentUri) to HttpServletRequest

Try {chain.doFilter (servletRequest, servletResponse);} catch (IOException ex) {throw ex;} catch (Exception ex) {/ / Try to extract a SpringSecurityException from the stacktrace Throwable [] causeChain = throwableAnalyzer.determineCauseChain (ex) UserRedirectRequiredException redirect = (UserRedirectRequiredException) throwableAnalyzer. GetFirstThrowableOfType (UserRedirectRequiredException.class, causeChain); if (redirect! = null) {/ / 2, determine whether the current exception UserRedirectRequiredException object is empty redirectUser (redirect, request, response) / / 3. Redirect access authorization service / oauth/authorize} else {if (ex instanceof ServletException) {throw (ServletException) ex;} if (ex instanceof RuntimeException) {throw (RuntimeException) ex } throw new NestedServletException ("Unhandled exception", ex);}    Debug take a look:! [Wechat Picture _ 20190916173425.png] (https://cache.yisu.com/upload/information/20210524/347/787918.jpg)    entire filter is divided into three steps:-1, record the current address (currentUri) to HttpServletRequest-2, determine whether the current exception UserRedirectRequiredException object is empty-3, redirect access authorization service / oauth/authorize # 3, The work of OAuth3ClientAuthenticationProcessingFilter    OAuth3ClientContextFilter filter is to call the authorization service / oauth/token interface to obtain token information through the acquired code. And the obtained token information is parsed into OAuth3Authentication authentication object. The origin is as follows:

@ Override public Authentication attemptAuthentication (HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

OAuth3AccessToken accessToken; try {accessToken = restTemplate.getAccessToken (); / / 1. Call the authorization service to get token} catch (OAuth3Exception e) {BadCredentialsException bad = new BadCredentialsException ("Could not obtain access token", e); publish (new OAuth3AuthenticationFailureEvent (bad)); throw bad } try {OAuth3Authentication result = tokenServices.loadAuthentication (accessToken.getValue ()); / / 2. Parse the token information as an OAuth3Authentication authentication object and return if (authenticationDetailsSourceSource authentication null) {request.setAttribute (OAuth3AuthenticationDetails.ACCESS_TOKEN_VALUE, accessToken.getValue ()) Request.setAttribute (OAuth3AuthenticationDetails.ACCESS_TOKEN_TYPE, accessToken.getTokenType ()); result.setDetails (authenticationDetailsSource.buildDetails (request));} publish (new AuthenticationSuccessEvent (result)); return result } catch (InvalidTokenException e) {BadCredentialsException bad = new BadCredentialsException ("Could not obtain user details from token", e); publish (new OAuth3AuthenticationFailureEvent (bad)); throw bad;}}    entire filter 2-point function:-restTemplate.getAccessToken (); / / 1. Call authorization service to obtain token-tokenServices.loadAuthentication (accessToken.getValue ()) / / 2. Parsing token information into OAuth3Authentication authentication object and returning    is a normal security authorization authentication process after completing the above steps. I will no longer talk about it here. Students who are not clear can take a look at the relevant articles I wrote. # 4. AuthorizationCodeAccessTokenProvider    did not mention one thing when talking about OAuth3ClientContextFilter, that is, who threw UserRedirectRequiredException. There is also one thing that is not mentioned when talking about OAuth3ClientAuthenticationProcessingFilter, that is, how it determines whether the current / login belongs to the step that needs to obtain the code or the step to obtain the token (of course, it is to determine whether / login has a code parameter, which is mainly about who determines it). These two points are designed to AuthorizationCodeAccessTokenProvider this class. When was this class called? The OAuth3ClientAuthenticationProcessingFilter is actually hidden in restTemplate.getAccessToken (); here is the accessTokenProvider.obtainAccessToken () called internally by this method. Let's take a look at the internal source code of OAuth3ClientAuthenticationProcessingFilter's obtainAccessToken () method:

Public OAuth3AccessToken obtainAccessToken (OAuth3ProtectedResourceDetails details, AccessTokenRequest request) throws UserRedirectRequiredException, UserApprovalRequiredException, AccessDeniedException, OAuth3AccessDeniedException {

AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) details; if (request.getAuthorizationCode () = = null) {/ / 1, determine whether the current parameter contains the code if (request.getStateKey () = = null) {throw getRedirectForAuthorization (resource, request); / / 2, throw a UserRedirectRequiredException exception} obtainAuthorizationCode (resource, request) if it does not contain } return retrieveToken (request, resource, getParametersForTokenRequest (resource, request), getHeadersForTokenRequest (request)) / / 3, include, call to get token} part of the whole method 3 steps:-1, determine whether the current parameter contains code-2, if not, throw UserRedirectRequiredException exception-3, include continue to obtain token   , and finally some students may ask, why did the first client jump to the authorization service login page, but when asked the second client did not? In fact, the two client single point process is the same, are authorization code mode, but why client 2 does not need to log in? In fact, it is because of Cookies/Session, because we access the same two clients are basically in the same browser. Students who do not believe can try two browsers to access two single-point clients. # 3. Personal summary    single sign-on is essentially an authorization code mode, so it is easy to understand, if you have to give a flow chart The same authorization code flow chart:! [https://cache.yisu.com/upload/information/20210524/347/787919.jpg](https://cache.yisu.com/upload/information/20210524/347/787919.jpg)    this article introduces JWT-based single sign-on (SSO) development and principle parsing development code that can access the code repository. Github address of the project: https://github.com/BUG9/spring-security    * * if you are interested in these, you are welcome to support star, follow, favorites and retweets! * * this is the end of the introduction of "what is the development and principle of JWT's single sign-on SSO". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report