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

  • 相关阅读:
    打印图片的属性和实现另存图片功能以及使用numpy
    opencv3.3 安装环境教程以及实现个图片读取功能
    在linux 创建网络会话和绑定两块网卡
    安装yum仓库
    C#添加错误日志信息
    关于使用宏将csv批量转换成xls的分享
    C#关于MySQL中文乱码问题
    无法启动iis express web服务器解决
    关于关闭WPS锁屏屏保及设置电脑自动关闭显示屏及休眠的分享
    为什么QQ能上却打不开网页呢?
  • 原文地址:https://www.cnblogs.com/helloz/p/9418524.html
Copyright © 2011-2022 走看看