zoukankan      html  css  js  c++  java
  • Spring Security

    Introduction

    Application security includes “authentication” and “authorization”:

    • “Authentication” is the process of establishing a principal is who they claim to be(a “principal” generally means a user, device or some other system which can perform an action in your application).
    • “Authorization” refers to the process of deciding whether a principal is allowed to perform an action within your application.

    Spring Security provides a deep set of authorization capabilities, they are divided into mainly three areas:

    • authorizing web requests
    • authorizing whether methods can be invoked
    • authorizing access to individual domain object instances

    maven dependencies:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>5.0.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>5.0.6.RELEASE</version>
    </dependency>
    

    The major building blocks of Spring Security:

    • SecurityContextHolder, to provide access to SecurityContext.
    • SecurityContext, to hold the Authentication and possibly request-specific security imformation.
    • Authentication, to represent the principal in a Spring Security-specific manner.
    • GrantedAuthority, to reflect the application-wide permissions granted to a principal.
    • UserDetails, to provide the necessary information to build an Authentication object from your application’s DAOs or other source of security data.
    • UserDetailsService, to create a UserDetails when passed in a String-based username( or certificate ID or the like).

    The authentication process within Spring Security:

    1. The username and passwod are obtained and combined into an instance of UsernamePasswordAuthenticationToken (an instance of Authentication interface)
    2. The token is passed to an instance of AuthenticationManager for validation.
    3. The AuthenticationManager returns a fully populated Authentication instance on successful authentication.
    4. The security context is established by calling SecurityContextHolder.getContext().setAuthentication(...), passing in the authentication object.

    Integrate with Spring MVC

    Refister the springSecurityFilterChain Filter for every URL in application. After that we would ensure that WebSecurityConfig was loaded in out existing ApplicationInitializer.

    public class MvcWebApplicationInitializer extends
            AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[] { WebSecurityConfig.class };
        }
    
        // ... other overrides ...
    }
    

    HttpSecurity

    Implement interface WebSecurityConfigurerAdapter and override the config method like what below do:

    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()                                                                1
                .antMatchers("/resources/**", "/signup", "/about").permitAll()                  2
                .antMatchers("/admin/**").hasRole("ADMIN")                                      3
                .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            4
                .anyRequest().authenticated()                                                   5
                .and()
            // ...
            .formLogin();
    }
    

    If you do not specify a login page, Spring Security will generate one automatically.

    Handling Logouts

    Spring Security logout progress:

    • Invalidating the HTTP Session
    • Cleaning up any RememberMe authentication that was configured
    • Clearing the SecurityContextHolder
    • Redirect to /login?logout
      You can custom logout action by the config method as well.
    LogoutHandler

    Generally, LogoutHandler implementations indicate classes that are able to participate in logout handling. They are expected to be invoked to perform necessary clean-up. As such they should not throw exceptions. Various implementations are provided:

    • PersistentTokenBasedRememberMeServices
    • TokenBasedRememberMeServices
    • CookieClearingLogoutHandler
    • CsrfLogoutHandler
    • SecurityContextLogoutHandler
    LogoutSuccessHandler

    Called after a successful logout by the LogoutFilter, to handle e.g redirection or forwarding to the appropriate destination.
    implementations:

    • SimpleUrlLogoutSuccessHandler
    • HttpStatusReturningLogoutSuccessHandler

    Authentication

    JDBC Authentication

    Java config example as below:

    @Autowired
    private DataSource dataSource;
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // ensure the passwords are encoded properly
        UserBuilder users = User.withDefaultPasswordEncoder();
        auth
            .jdbcAuthentication()
                .dataSource(dataSource)
                .withDefaultSchema()
                .withUser(users.username("user").password("password").roles("USER"))
                .withUser(users.username("admin").password("password").roles("USER","ADMIN"));
    }
    
    Custom Authentication
    1. AuthenticationProvider
      You can define custom authentication by exposing a custom AuthenticationProvider as a bean.For example, the following will customize authentication assuming that SpringAuthenticationProvider implements AuthenticationProvider:
      @Bean
      public SpringAuthenticationProvider springAuthenticationProvider() {
       return new SpringAuthenticationProvider();
      }
      
    2. UserDetailsService
      You can define custom authentication by exposing a custom UserDetailsService as a bean. For example, the following will customize authentication assuming that SpringDataUserDetailsService implements UserDetailsService:
      @Bean
      public SpringDataUserDetailsService springDataUserDetailsService() {
       return new SpringDataUserDetailsService();
      }
      
      You can also customize how passwords are encoded by exposing a PasswordEncoder as a bean. For example, if you use bcrypt you can add a bean definition as shown below:
      @Bean
      public BCryptPasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
      }
      

    Multiple HttpSecurity

    We can configure multiple HttpSecurity instances just as we can have multiple blocks. The key is to extend the WebSecurityConfigurationAdapter multiple times.

    @EnableWebSecurity
    public class MultiHttpSecurityConfig {
        @Bean
        public UserDetailsService userDetailsService() throws Exception {
            // ensure the passwords are encoded properly
            UserBuilder users = User.withDefaultPasswordEncoder();
            InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
            manager.createUser(users.username("user").password("password").roles("USER").build());
            manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
            return manager;
        }
    
        @Configuration
        @Order(1)
        public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
            protected void configure(HttpSecurity http) throws Exception {
                http
                    .antMatcher("/api/**")
                    .authorizeRequests()
                        .anyRequest().hasRole("ADMIN")
                        .and()
                    .httpBasic();
            }
        }
    
        @Configuration
        public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                    .authorizeRequests()
                        .anyRequest().authenticated()
                        .and()
                    .formLogin();
            }
        }
    }
    

    Method Security

    From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It provides support for JSR-250 annotation security as well as the framework’s original @Secured annotation. From 3.0 you can also make use of new expression-based annotations.

    EnableGlobalMethodSecurity

    We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any @Configuration instance. For example, the following would enable Spring Security’s @Secured annotation.

    @EnableGlobalMethodSecurity(securedEnabled = true)
    public class MethodSecurityConfig {
    // ...
    }
    

    Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. Spring Security’s native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:

    public interface BankService {
    
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public Account readAccount(Long id);
    
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public Account[] findAccounts();
    
    @Secured("ROLE_TELLER")
    public Account post(Account account, double amount);
    }
    

    Support for JSR-250 annotations can be enabled using

    @EnableGlobalMethodSecurity(jsr250Enabled = true)
    public class MethodSecurityConfig {
    // ...
    }
    

    These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security’s native annotations. To use the new expression-based syntax, you would use

    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class MethodSecurityConfig {
    // ...
    }
    

    the java code would be

    public interface BankService {
    
    @PreAuthorize("isAnonymous()")
    public Account readAccount(Long id);
    
    @PreAuthorize("isAnonymous()")
    public Account[] findAccounts();
    
    @PreAuthorize("hasAuthority('ROLE_TELLER')")
    public Account post(Account account, double amount);
    }
    

    full list:
    @PreAuthorize
    @PostAuthorize
    @PostFilter- filter the result
    @PreFilter:filter the param

  • 相关阅读:
    【bzoj1010-toy】斜率优化入门模板
    【bzoj1096-仓库建设】斜率优化
    【bzoj1911-[Apio2010]特别行动队】斜率优化
    【bzoj1597- [Usaco2008 Mar]土地购买】斜率优化
    【bzoj4310/hdu5030-跳蚤】后缀数组
    【bzoj2219-数论之神】求解x^a==b(%n)-crt推论-原根-指标-BSGS
    HDU6301 Distinct Values (多校第一场1004) (贪心)
    HDU6299 Balanced Sequence (多校第一场1002) (贪心)
    HDU6298 Maximum Multiple (多校第一场1001)
    NYOJ1238 最小换乘 (dijkstra)
  • 原文地址:https://www.cnblogs.com/helloz/p/9418524.html
Copyright © 2011-2022 走看看