天天看點

springboot 整合 security 實作自定義登陸頁面

自定義登陸頁面 和踢出線上使用者

  1. 引入 jar
<!--頁面使用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
         </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
           
  1. 建立使用者接口
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UserService extends UserDetailsService {
}
           
  1. 實作使用者接口
package com.gupaoedu.security.service.impl;

import com.gupaoedu.security.service.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

 
@Service
public class UserServiceImpl implements UserService {



    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    /**
     * 實作自定義的認證流程
     *
     * @param 
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       
        List<GrantedAuthority> authorities = new ArrayList<>();
        SimpleGrantedAuthority auth = new SimpleGrantedAuthority("ROLE_ROOT");
        authorities.add(auth);
        // 資料庫操作
        //.....根據username查詢對應使用者 role 和密碼...
        //這裡密碼 直接寫死了
        //bCryptPasswordEncoder  在MyWebSecurityConfigurer類中 實作了
        String password=bCryptPasswordEncoder.encode("123");
        UserDetails user = new User(username
                , password
                , true
                , true
                , true
                , true
                , authorities);


        return user;
    }
}

           
  1. 重寫 MyWebSecurityConfigurer 類
import com.gupaoedu.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


@Configuration
public class MyWebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private  BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
       //         .loginPage("/login.html")  
       //        .loginProcessingUrl("/login.do1")   這兩行注釋則使用預設的登陸頁面
       
        http.authorizeRequests() // 設定哪些頁面可以直接通路,哪些需要驗證
            .antMatchers("/login.html","/error.html").permitAll() // 放過
            .anyRequest().authenticated() // 剩下的所有的位址都是需要在認證狀态下才可以通路
            .and()
                .formLogin()
                .loginPage("/login.html") // 指定指定要的登入頁面
                .loginProcessingUrl("/login.do1") // 處理認證路徑的請求
                //認證成功後的跳轉頁面 預設是get方式送出 自定義成功頁面post方式送出
				//在 controller中處理時要注意
                .defaultSuccessUrl("/home.html")
                .failureForwardUrl("/error.html")
            .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login.html")
            .and().csrf().disable() //關閉跨域保護
                .sessionManagement()
                .maximumSessions(1);// 同一使用者 隻允許一個線上 自動踢出線上使用者
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }




}

           
  1. 控制器
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
@Controller
public class BaseController {

    @GetMapping("/login.html")
    public String loginPage(){
        return "/login.html";
    }

    @RequestMapping("/home.html")
    public String home(){
        return "/home.html";
    }

    @GetMapping("/")
    public String basePage(){
        return "/home.html";
    }

    @GetMapping("/error.html")
    public String error(){
        return "/error.html";
    }
}

           
  1. 登陸頁面 login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登入管理</h1>

    <form th:action="@{/login.do1}" method="post">
        賬号:<input type="text" name="username"><br>
        密碼:<input type="password" name="password"><br>
        <input type="submit" value="登入"><br>
    </form>
</body>
</html>
           
  1. home.html頁面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <h1>首頁</h1>
</body>
</html>