Realize SP single sign-on based on SAML protocol

Realize single sign-on SAML SP end based on SAML protocol and Spring Security

1. What is SAML protocol

First, let’s briefly introduce what SAML protocol is:
SAML stands for Security Assertion Markup Language. The full English name is Security Assertion Markup Language. It is an XML-based standard for exchanging authentication and authorization data between different security domains. The SAML standard defines an identity provider and a service provider, which constitute the different security domains mentioned above. SAML is a product of the Security Services Technical Committee of the OASIS organization.
SAML (Security Assertion Markup Language) is an XML framework, which is a set of protocols that can be used to transmit security statements. For example, two remote machines need to communicate. In order to ensure security, we can use encryption and other measures, or use SAML to transmit. The transmitted data is in the form of XML and conforms to the SAML specification, so that we do not require the two machines to use What kind of system only requires an understanding of the SAML specification, which is obviously better than traditional methods. The SAML specification is a set of Schema definitions.
It can be said that in the Web Service domain, the schema is the specification, and in the Java domain, the API is the specification.

For those who haven't used Spring Security, here is the official document

2. The role of SAML and related definitions

1. Function

Authentication statement: declare whether the user has been authenticated, usually used for single sign-on.
Attribute declaration: Declare the attributes of a subject.
Authorization decision statement: Declare the authority of a certain resource, that is, a user has the given E authority on resource R and can perform A operation.
If you want to have a deeper understanding of the SAML protocol, see here, here is attached (Xia Xia, Wei Young) a detailed explanation of the SAML protocol (one, two, and three chapters)

2. Composition

SP (Service Provider): An entity that provides formal business services to users, usually needs to authenticate a user's identity;
IDP (Identity Provider): Provides user identity authentication to ensure that the user is the declared identity
assertion (Assertions) that is information: Assertions are used to describe the object of authentication in SAML, including when and how the user is authenticated, and can also include some extended information, such as the user's Email address and phone number.

Protocol (Protocol) is communication: the protocol specifies how to perform different actions. These behaviors are refined into a series of Request and Response objects, and these requests and corresponding objects contain the information specifically required by the behavior. For example, the AuthnRequest Protocol specifies how an SP requests to obtain an authenticated user.

Binding is transmission: Binding defines how SAML information is transmitted using the communication protocol. For example, HTTP redirection binding states that SAML information will be transmitted through HTTP redirection messages; another example is SAML SOAP binding, which states that SAML messages are transmitted via SOAP. For example, AuthnRequest above declares Http-POst binding

MetaData: SAML metadata is configuration data, which contains information about the parties in the SAML communication, such as the ID of the other party in the communication, the IP address of the Web Service, the supported binding types, and the keys used in the communication and many more.

3. SAML process analysis

This picture illustrates the following steps.
1. The user tries to access WebApp1.

2. WebApp1 generates a SAML authentication request. The SAML request will be encoded and embedded in the URL of the SSO service. The RelayState parameter containing the encoded URL of the WebApp1 application that the user is trying to access is also embedded in the SSO URL. The RelayState parameter is used as an opaque identifier and will be directly returned to the identifier without any modification or inspection.

3. WebApp1 sends the redirect to the user's browser. The redirect URL contains the encoded SAML authentication request that should be submitted to the SSO service.

4. SSO (Unified Authentication Center or Identity Provider) decodes the SAML request and extracts the ACS (Declaration of Customer Service) URL of WebApp1 and the user's target URL (RelayState parameter). Then, the unified authentication center authenticates the user. The unified authentication center may require valid login credentials or check valid session cookies to verify the user's identity.

5. The unified authentication center generates a SAML response that contains the username of the authenticated user. According to the SAML 2.0 specification, this response will be digitally signed using the DSA/RSA public key and private key of the unified certification center.

6. The unified authentication center encodes the SAML response and RelayState parameters, and returns the information to the user's browser. The unified certification center provides a mechanism so that the browser can forward this information to the WebApp1 ACS.

7. WebApp1 uses the public key of the unified certification center to verify the SAML response. If the response is successfully verified, ACS will redirect the user to the destination URL.
8. The user will be redirected to the target URL and log in to WebApp1.

Four. Open source projects in Git

1. Complete SAML SP and IDP to achieve a simple Demo address for communication

https://github.com/OpenConext/Mujina

2. SAML SP based on Spring Security (note that there is only SP) project address

https://github.com/vdenotaris/spring-boot-security-saml-sample.git

3. Here is my own demo of the configuration version SP implemented based on the previous one. The white code is more spicy. Welcome to the great god

https://github.com/jwu09188/saml-sso-sp-spring-security

This project is made into a simple SP framework. There is no startup class inside. If you want to use a new project to realize external reference as a jar package, note (remember to add bean scan annotation scan to your startup class) you need to configure yml, Liezi as follows:

server:
  port: 9090
logging:
  file: logs/file.log
  level:
    com:
      jiujin:
        web:
          saml: DEBUG
    org:
      opensaml: DEBUG
      springframework:
        security:
          saml: DEBUG
sso:
  saml:
    sp:
      # Entity ID of the SP  
      sp_entity_id: com:saml:spring:sp
      # Certificate
      sp_Certificate: MIIEzTCCAzWgAwIBAgIUdsfVXEJJbdL+K7FmAiBlXgLEg/owDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB1NJQ0hVQU4xEDAOBgNVBAcMB0NIRU5HRFUxDzANBgNVBAoMBkpJVUpJTjELMAkGA1UECwwCUkQxEDAOBgNVBAMMB0NHV1lDT00xEzARBgkqhkiG9w0BCQEWBFVVVVUwHhcNMjAwNzE1MDgyMTU3WhcNMzAwNzE1MDgyMTU3WjB2MQswCQYDVQQGEwJDTjEQMA4GA1UECAwHU0lDSFVBTjEQMA4GA1UEBwwHQ0hFTkdEVTEPMA0GA1UECgwGSklVSklOMQswCQYDVQQLDAJSRDEQMA4GA1UEAwwHQ0dXWUNPTTETMBEGCSqGSIb3DQEJARYEVVVVVTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBANWpWb41MrSLIWsdelCYRxySClXcvEF6l69f+EX877xY89EVH48xnckH6u4IciFXGaAavRR2RLOe4uBf+RU8Kk9+EuJL5tFVYOo4Wf0p4c6Bf62IhiUOpDKPTaaGCnDBR2ZiC6enpMYbMHxJ/HSbWCoBodH81le7NBekE0YNtGLaesX9so5mYbVURnKhpM5oX0OAo20wvZBomK76Zi6pEj9zJzzbCahWtkkutJLf2Z8DQHweEEouKzoo3USNpD7/VdRjvMw/mJwAIPupipJvQH7s2jMkt/CDFdd7SQr+CxccVPC1phkBQygwDK4SZok0qhQv4FFpSKWUVQTUPMw37cPG2dZ+Up4bPYp48tmDp1qP1PPpbmNGUBqrwR6B9vQ635xrr2By7i9PlkzUz2BQ3hvlXZ39aW4cmzRomN3AldWuoj7nzEdyeJJI5/8zs7ETqInnVqrEjKwU4bkSZu6hZR5+YKgr1KZ37itXryyXxv324g1QLZ7FMaXtlNmTRIF7BwIDAQABo1MwUTAdBgNVHQ4EFgQUQQzvKnZNr/6tZaDBEjcoCN5fiuYwHwYDVR0jBBgwFoAUQQzvKnZNr/6tZaDBEjcoCN5fiuYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAYEAYwrZZ+OgsVXVJlYVHHVrOLXOvaee/c3DFarpwu1VW3hsRWOToGrSMybly0atY5pAYT/rka6rDHW/8W1RB0uaDLI8HYcwyH/7VQvq3uqO8QO/QAbXUAQYjAQSexIu0DV2JFw/SQN4KOt5j/A4gL4Cw4bg0ZosHbH40ZHgeo49MLvyYDzXk1SbwFVO1HonAlEtElcrwcvYLNiqr7Arvb9tb8pmDQIR94LwfNEc4jikcuAOH5Lh/G3tiaewQdkxeUPG+HXgwR8OV51dVTOkOhJVQeioE1ZUKniIcuukCDY/vFBihYCy+Pfver0C39ECllu9vfYuSogfBQ09c5HPkDG0Q428RHDHQbKLP9K3pd6Vw3x2a5Yj3SgcDQ19I5IChS6WmIlU4pTfljWc1kfc+wQ/Fp7jXXzEz9gOVPtf9840SJX3119g9d5T19mH8mj5MbeiY10BOAJzZXQNeWcNBEJu7yNQ6/gBoCaZXAYI6xLZk7oFmZNGpjmCbw9BhtbJ6WDZ
      # Passphrase of the keystore
      sp_passphrase: secret
      # private key
      sp_private_key: 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
      # Resource URL for the idp metadata idp  
      idp_metadata_url: idp的metadata地址  
      # IDP Discovery Service fill in what you need to be found controller
      idp_discovery_service: /saml-sso/sp/login-redirect
      # jump address after successful login url
      redirection_after_successful_url: https://www.baidu.com

note! ! The idp_discovery_service in the configuration file: /saml-sso/sp/login-redirect Discovery service Here is the controller you define yourself that needs to be discovered by idp

Friends who don’t
know how to generate private keys and certificates can click here for the generation tutorial of (Slipper). An example of a local port whose prefix is ​​defined by yourself:

localhost:9090/saml-sso/sp/metadata
SP metadata获取地址: .../saml-sso/sp/metadata
登出地址: .../saml-sso/sp/logout-redirect
登录地址: .../saml-sso/sp/login

All of the above addresses can be modified to what you need in the samlFilter() method of the WebSecurityConfig class. Note: You need to click in the samlEntryPoint() method passed in the method to see if there are any settings and addresses. You also need to modify them.

 /**
     * 定义安全筛选器链,以便通过使用SAML 2.0支持SSO身份验证
     *
     * @return Filter chain proxy
     * @throws Exception
     */
    @Bean
    public FilterChainProxy samlFilter() throws Exception {
    
    
        List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>();
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/login/**"),
                samlEntryPoint()));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/logout-redirect/**"),
                samlLogoutFilter()));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/metadata/**"),
                metadataDisplayFilter()));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/assert"),
                samlWebSSOProcessingFilter()));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/single-logout/**"),
                samlLogoutProcessingFilter()));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml-sso/sp/login-redirect/**"),
                samlIDPDiscovery()));
        return new FilterChainProxy(chains);
    }

After the specified logout is successful, you need to jump to the address to modify the successLogoutHandler() method, set successLogoutHandler.setDefaultTargetUrl(); set the address you need

  @Bean
    public SimpleUrlLogoutSuccessHandler successLogoutHandler() {
    
    
        SimpleUrlLogoutSuccessHandler successLogoutHandler = new SimpleUrlLogoutSuccessHandler();
        successLogoutHandler.setDefaultTargetUrl("/saml-sso/sp/login-redirect");
        return successLogoutHandler;

One last thing to note is
that the other methods in the project are not all introduced. There are comments in the project.

Here is my first blog, which is just a rough study of SAML-based single sign-on applications. I have limited knowledge. Please predecessors for advice. At the same time, I take this blog post to share my learning experience, and to start a discussion.

Guess you like

Origin blog.csdn.net/weixin_45584768/article/details/107792403