Spring Security Quick View

Source: Internet
Author: User

Prior to spring security

I used to Interceptor implement a simple website demo of the login interception and session processing work, although the ability to achieve the corresponding functions, but no doubt spring security provides a more simple configuration method to better protect the Web application.

Related structures of Spring security

Here you can refer to spring Security's official introduction document: Spring-security-architecture
In simple terms:

    • Spring security is a single Filter , and its specific type is FilterChainProxy that it is configured as @Bean in ApplicationContext .
    • From the container's point of view, Spring security is a single filter, but there are a lot of extra filter, each of which plays their respective roles, as shown in:

    • Spring Security's authentication, which is mainly AuthenticationManager done by this interface, is the main method of verifyingauthenticate()

public interface AuthenticationManager {         Authentication authenticate(Authentication authentication)       throws AuthenticationException;      }
    • This method can accomplish three things:
      • If it can verify that the input represents a valid principal, it returns one Authentication (usually included authenticated=true )
      • If it can verify that the input represents an invalid principal, throw aAuthenticationException
      • If it can't decide, it's back.null
    • The most common AuthicationManager implementation is ProviderManager that it delegates it to AuthticationProvider this instance, AuthenticationProvider and AuthenticationManager a little bit like it, but contains some extra methods to allow the caller to query whether the form is supported Authenticaion .
public interface AuthenticationProvider {          Authentication authenticate(Authentication authentication)               throws AuthenticationException;          boolean supports(Class<?> authentication);      }    

supports()The argument in the method Class<?> is Class<? extends Authentication> that it only asks if it supports passing to the authenticate() method.

    • In the same program, one can ProviderManager support several different authentication mechanisms by delegating a series of them, and AuthenticaitonProviders if ProviderManager a particular instance type is not recognized Authentication , it is skipped.
    • Many times, a program contains multiple resource protection logical groups, each with their own unique AuthenticationManager , usually they share the parent, then the parent becomes one "global"资源 , as all provider the backs.

    • Spring Security offers a number of configurations that help us quickly turn on validation, and most commonly AuthenticationManagerBuiler , it's good at memory (in-memory), JDBC, LDAP, or personal customization UserDetailService .

Using spring security for access and permission control

Note: This follow-up code is implemented with Springboot as the framework, and its Demo Git:spring-security-demo

    • Access and privilege control mainly through the Configure method of overloading Websecurityconfigureradapter
Method Description
Configure (Websecurity) Configure spring Security's filter chain by overloading
Configure (Httpsecurity) Configuring how interceptor protection requests are through overloading
Configure (Authenticationmanagerbuilder) Configuring the User-detail service with overloading
    • We rewrite the following methods:
    @Override protected void Configure (Httpsecurity http) throws Exception {http. authorizerequests () . Antmatchers ("/index"). Hasanyauthority ("Role_user", "Role_admin"). Antmatchers ("/oss"). Hasauthority ("ROLE_ADMIN "). Antmatchers (Httpmethod.get,"/login "). Permitall (). Anyrequest (). authenticated (). and (). fo        Rmlogin (). LoginPage ("/login"). Permitall ()//.successhandler (Successhandler). and (). Logout ()    . Logoutsuccessurl ("/"). Permitall (); } @Override protected void Configure (Authenticationmanagerbuilder auth) throws Exception {Auth.inmemorya Uthentication (). Passwordencoder (New Bcryptpasswordencoder ()). Withuser ("root"). Password (new Bcryptpassworde Ncoder (). Encode ("root")). Roles ("USER", "ADMIN"). and (). Withuser ("normal"). Password (new Bcryptpasswordencoder        (). Encode ("normal")). Roles ("USER");     Auth.authenticationprovider (Userprovider);   Auth.authenticationprovider (Afterprovider); }
 -url matching via ' antmatchers () ', then corresponding processing, such as the code, we intercepted the **/index** and **/oss** two links, respectively, required to have ' role_user ' or ' Role_ ADMIN ', ' role_admin ' to access the two identities. -' Anyrequest (). Authenticated () ' means that other requests will need to be verified-' formlogin () ' To have the login page, and if there is no subsequent ' loginpage () ', a spring will be generated by default Security page, and the later commented out ' Successhandler ' is the next. -' Permitall () ' indicates that the current connection does not require authentication. -' logout () ' Will intercept the **\logout** request, complete the logout operation, ' Logoutsuccessurl () ' is the redirected address after logout. -' and () ' in which the connection works. 
    • Some common ways to configure protection paths
      • Authenticated (): Allow authenticated user access
      • Denyall (): Unconditional denial of all access
      • Fullyauthenticated (): If the user is fully authenticated (not through remeber me) access
      • Hasipadress (String): If you are riding a cow from a given IP address, you can access
      • Hasanyauthority (String ...): If used with any given role, you can access
      • Hasanthority (String): If the user has a given role, they can access
      • Permital (): unconditional Allow method
      • Remeberme (): If the user is authenticated by Remeber-me, they can access
      • In addition, with autheority to have a ROLE, both is a concept, autheority must start with "Role_", and ROLE does not need, see the code.
    • At this point, our root account can access both the index and the OSS, and the normal account can only access index, cannot access the OSS, if access to OSS will appear:
      There is an unexpected error (Type=forbidden, status=403).

    • Above we have generated two memory user root and normal by overloading configure (Authenticationmanagerbuilder auth), and we can do so through JDBC.

Processing after successful certification through Authenticationsuccesshandler
    • By implementing the Authenticationsuccesshandler interface, we can execute the corresponding code after the validation is successful, such as Token settings and so on, such as I now print a login information and redirect the request to the first page
@Componentpublic class SuccessHandler implements AuthenticationSuccessHandler{    @Override    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,            Authentication authentication) throws IOException, ServletException {        System.out.println(authentication.getName()+" is loging , role is"+authentication.getAuthorities());        response.sendRedirect("/");            }
    • and add it to the formLogin() post, namely:
.formLogin()        .loginPage("/login")        .permitAll().successHandler(successHandler)
    • Log in to the root account again, and you'll see it on the console: root is loging, role is[role_admin, Role_user]
Personalized authentication via Authenticationprovider
    • We create a userauthprovider and let it implement the Authenticationprovider interface:
@Override Public authentication Authenticate (authentication authentication) throws Authenticationexception {        System.out.println ("-----------------------------------------------------------------------");                System.out.println ("This is Userauthprovider");        SYSTEM.OUT.PRINTLN ("Starting authenticate ...");        System.out.println ("Credentials:" +authentication.getcredentials ());        System.out.println ("Name:" +authentication.getname ());        System.out.println ("Class:" +authentication.getclass ());        System.out.println ("Details:" +authentication.getdetails ());        System.out.println ("Principal:" +authentication.getprincipal ());        System.out.println ("-----------------------------------------------------------------------"); Usernamepasswordauthenticationtoken auth=new Usernamepasswordauthenticationtoken (Authentication.getPrincipal (),        Authentication.getcredentials ());    return auth; } @Override Public Boolean supportS (class<?> authentication) {SYSTEM.OUT.PRINTLN ("This is Userauthprovider");        SYSTEM.OUT.PRINTLN ("starting supports");        System.out.println (Authentication.getclass ());    return false; }
    • At the same time, we comment out the previous auth.inMemoryAuthentication() , add Userauthprovider to the AuthenticationManagerBuilder , namely:
    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {//      auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//              .withUser("root").password(new BCryptPasswordEncoder().encode("root")).roles("USER","ADMIN").and()//              .withUser("normal").password(new BCryptPasswordEncoder().encode("normal")).roles("USER");        auth.authenticationProvider(userProvider);        auth.authenticationProvider(afterProvider);            }
    • When we log in again, we will see that the console will output
    This is UserAuthProvider       starting supports       java.lang.  
    • The reason is that we override the supports() method, always return False, and return false, that is no longer called authenticate() for the authentication operation (as described above), we will supports() return the value of True, login again (username:root password : 1234), the console will output
This is UserAuthProviderstarting supportsclass java.lang.Class-----------------------------------------------------------------------This is UserAuthProviderstarting authenticate ... ...Credentials:1234Name:rootClass:class org.springframework.security.authentication.UsernamePasswordAuthenticationTokenDetails:org.sprin[email protected]166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: node04v47liue6knt1oghnzgiqb9dx0Principal:root-----------------------------------------------------------------------root is loging , role is[]
    • was successfully logged in because we declared an instance of authentication directly in the authenticate () method Usernamepasswordauthenticationtoken , and returns, as stated above, when the authentication instance is returned, the default is authorization succeeds, and if we return null , the description cannot be determined and the login is not successful.

    • At this point we create an object Userafterprovider , which also implements the Authenticationprovider interface, and will The Userafterprovider and userauthprovider authenticate () return values are set to null . We use the above data again to log in, the console output is as follows:

This is userauthproviderstarting Supportsclass Java.lang.Class-----------------------------------------------------------------------This is Userauthproviderstarting Authenticate ... Credentials:1234name:rootclass:class org.springframework.security.authentication.usernamepasswordauthenticationtokendetails:org.sprin[email  Protected]43458:remoteipaddress:0:0:0:0:0:0:0:1; Sessionid:node01m47f3t6xq5a470fu07jaipzb0principal: Root-----------------------------------------------------------------------This is userafterproviderstarting Supportsclass Java.lang.Class-----------------------------------------------------------------------This is Userafterproviderstarting Authenticate ... Credentials:1234name:rootclass:class org.springframework.security.authentication.usernamepasswordauthenticationtokendetails:org.sprin[email  Protected]43458:remoteipaddress:0:0:0:0:0:0:0:1; SessionId:node01m47f3t6xq5a470fu07jaipzb0Principal:root----------------------------------------------------------------------- 
    • , which is two porvider verified, did not pass (return null), stating that all validations that join Authenticationmanagerbuilder are performed once, So if we restore one of the provider authenticate () return values to the authentication instance and log in again, the console will output the following result:
This is userauthproviderstarting Supportsclass Java.lang.Class-----------------------------------------------------------------------This is Userauthproviderstarting Authenticate ... Credentials:1234name:rootclass:class org.springframework.security.authentication.usernamepasswordauthenticationtokendetails:org.sprin[email  Protected]166c8:remoteipaddress:0:0:0:0:0:0:0:1; Sessionid:node04v47liue6knt1oghnzgiqb9dx0principal: Root-----------------------------------------------------------------------root is loging, role Is[]this is Userauthproviderstarting Supportsclass Java.lang.Class-----------------------------------------------------------------------This is Userauthproviderstarting Authenticate ... Credentials:nullName:rootClass:class org.springframework.security.authentication.usernamepasswordauthenticationtokendetails:org.sprin[email  Protected]166c8:remoteipaddress:0:0:0:0:0:0:0:1; SessionId:node04v47liue6knt1oghnzgiqb9dx0Principal:root----------------------------------------------------------------------- 
    • Because we rewrote it AuthenticationSuccessHandler , so verify that the success of the regret redirect to /, and my controller in the / another redirect to /index, so there was two verification, and this time we found that because UserAuthProvider Passed, so there is UserAfterProvider no validation, so we can know that as long as there is a provider passed the validation we can think passed the validation.

    • Therefore, we can AuthenticationProvider write some of our own authentication logic through implementation, and even @autowire the related service to assist the implementation.

Spring Security Quick View

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.