springsecurity

1.定義

Spring Security是一個可以爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組能夠在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減小了爲企業系統安全控制編寫大量重複代碼的工做。html

https://springcloud.cc/spring-security-zhcn.html   中文版參考手冊spring

2.基本原理:一組過濾器鏈

UsernamePasswordAuthenticationFilter:用戶認證數據庫

ExceptionTranslation:異常處理編程

FilterSecurityInterceptor:最終確認是否能登陸的攔截器json

備註:在沒有驗證的狀況下,登陸後會到默認的驗證頁面,默認會攔截全部頁面,待驗證成功後會轉到相應的頁面安全

3.依賴app

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

4.Api簡要說明框架

authorizeRequests():請求受權dom

formLogin():表單登陸(表單登陸含兩部分一個是認證一個是受權)ide

anyRequest():任何請求

authenticated():身份認證

httpBasic():httpBasic認證方式

loginPage():指定登陸時的認證頁面,這裏有一個坑死循環須要注意。

antMatchers():匹配

permitAll():不須要身份認證

5.使用數據庫驗證登陸方式

@Configuration
@ComponentScan("springsecurity.demo")
@MapperScan("springsecurity.demo.Mapper")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()//表單登陸
                .and()
                .authorizeRequests()//權限認證
                .anyRequest()//任何請求
                .authenticated()//須要認證
        ;
    }
}
@Component
public class MyUserDetailsService  implements UserDetailsService {
    @Autowired
    UserMapper  userMapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) {
        //查詢表
        springsecurity.demo.domain.User userByName = userMapper.getUserByName(username);
        //加密
        String encode = passwordEncoder.encode(userByName.getPassword().toString());//應該是在放入數據庫的時候加密,這裏直接直接取出
        //將查詢的結果放入user中,
        // AuthorityUtils.commaSeparatedStringToAuthorityList("admin")表示角色admin(擁有的權限)
        return   new User(username,encode , AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));//須要採用加密方式否者出現{id}爲null
    }
}
@Configuration
public class SecurityBeanConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource  getdaDataSource(){
        return  new DruidDataSource();
    }
    @Bean
    public PasswordEncoder  getPasswordEncoder(){
        return  new BCryptPasswordEncoder();//springsecurity 內置的加密器,建議使用
    }
}
@RestController
public class UserController {
    @GetMapping("/hello")
    public String testLogin(){
        return  "helloworld  security";
    }
}

自定義加密方式

須要實現PasswordEncoder

重寫方法

encode:對密碼進行加密

matches(CharSequence var1, String var2):var1原密碼,var2傳過來的密碼

User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities)

enabled:是否可用

accountNonExpired:帳戶是否過時

credentialsNonExpired:密碼是否過時

accountNonLocked:是否被凍結

6.自定義登陸頁面

6.1使用默認的自定義方式配置

@Configuration
@ComponentScan("springsecurity.demo")
@MapperScan("springsecurity.demo.Mapper")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/logintest.html")  //登陸頁面定義
                .loginProcessingUrl("/authentication/logintest")//默認處理的是login  post
                .and()
                .authorizeRequests()
                .antMatchers("/logintest.html")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf().disable()//跨站域請求僞造關閉,注意不關閉在Chrome中沒反應
        ;
    }
}

 6.2使用自定義配置登陸頁面

@Configuration
@ComponentScan("springsecurity.demo")
@MapperScan("springsecurity.demo.Mapper")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    MySecurityProperties mySecurityProperties;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/logintest")
                .loginProcessingUrl("/authentication/logintest")
                .and()
                .authorizeRequests()
                .antMatchers("/logintest",mySecurityProperties.getLogin())
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf().disable()
        ;
    }
}
@RestController
public class UserController {
    HttpSessionRequestCache  cache= new  HttpSessionRequestCache();
    DefaultRedirectStrategy defaultRedirectStrategy =  new DefaultRedirectStrategy();//重定向頁面

    @Autowired
    MySecurityProperties securityProperties;

    @GetMapping("/logintest")
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Message  testAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SavedRequest savedRequest = cache.getRequest(request, response);
        if(savedRequest!=null){
            String redirectUrl = savedRequest.getRedirectUrl();//獲取請求地址
            if(StringUtils.endsWithIgnoreCase(redirectUrl, ".html")){
                defaultRedirectStrategy.sendRedirect(request, response, securityProperties.getLogin());
            }
        }
        return  new Message("請先登陸");
    }
}
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class Message implements Serializable {
    private   Object  mesaage;
}
<body>
    <h2  style="color: red">簡單的登陸頁面login</h2>
   <form  action="/authentication/logintest" method="post">
       <table>
           <tr>
               <td>帳號:</td>
               <td ><input type="text"  name="username"/></td>
           </tr>
           <tr>
               <td>密碼:</td>
               <td> <input type="password"  name="password"/></td>
           </tr>
           <tr>
               <td colspan="2" style="text-align: right"><input type="submit" value="提交" /></td>
           </tr>
       </table>
   </form>
</body>
</html>
@ConfigurationProperties("spring.security")
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
@Component
public class MySecurityProperties {
    private   String  login="/logintest.html";
}

 7.自定義成功登錄的返回值

@Configuration
@ComponentScan("springsecurity.demo")
@MapperScan("springsecurity.demo.Mapper")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    MySecurityProperties mySecurityProperties;

    @Autowired
    MyUserDetails  myUserDetails;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/logintest")
                .loginProcessingUrl("/authentication/logintest")
                .successHandler(myUserDetails)
                .and()
                .authorizeRequests()
                .antMatchers("/logintest",mySecurityProperties.getLogin())
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf().disable()
        ;
    }
}
@Component
public class MyUserDetails implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(new ObjectMapper().writeValueAsString(authentication));
    }
}

 失敗相似

實現AuthenticationFailureHandler實現onAuthenticationFailure方法

.failureHandler(AuthenticationFailureHandler  xxx)

8.圖片驗證

相關文章
相關標籤/搜索