springsecurity簡單使用

  1. pom.xml中加入springsecurity依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  1. 用戶對象實體
@Data
public class ProjectUser implements Serializable, UserDetails {

	private static final long serialVersionUID = 4702398324039042010L;
	
	// todo 用戶的其他屬性
	private String username;

    /**
     * 系統級別的用戶角色枚舉,可以修改成1,2,3存儲在db,節省空間
     */
    public enum UserRoleEnum {

        /**
         * 管理員
         */
        ROLE_ADMIN("ROLE_ADMIN", "管理員"),

        /**
         * 普通用戶
         */
        ROLE_NORMAL("ROLE_NORMAL", "普通用戶");
        private String key;
        private String value;

        private UserRoleEnum(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }	
}
  1. 無密碼編碼,如果需要密碼編碼直接在裏面編寫
public class NoPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence rawPassword) {
        return "";
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return true;
    }
}
  1. 用戶服務,公司的郵箱,直接登錄;如果是toc,需要用戶註冊,登錄分開寫
@Service
@Slf4j
public class UserService implements UserDetailsService {

	@Autowired
    private AuthenticationManager authenticationManager;

	/**
     * 通過用戶名加載用戶
     *
     * @param username
     * @return
     */
    @Override
    public UserDetails loadUserByUsername(String username) {
        ProjectUser user = null;//根據自己邏輯獲取用戶
        if (user == null) {
            throw new UsernameNotFoundException("用戶不存在");
        }
        return user;
    }
	
	/**
     * 登陸
     *
     * @param username
     * @return
     */
	public ProjectUser login(String username, String password) {
		// todo 校驗這個用戶,並登陸並授權
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, encoder.encode(password));
        //使用SpringSecurity攔截登陸請求 設置認證,爲了其他接口訪問進行用戶驗證
        Authentication authentication = authenticationManager.authenticate(upToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
		// todo 返回登陸的用戶信息
	}
	
}
  1. springsecurity的配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)  //post請求之前進行驗證
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

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

    /**
     * 如果是前後分離部署的,這個裏面不用寫靜態資源
     * 如果是前後端放在一起的,需要把靜態資源忽略驗證
     *
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .debug(false)
            .ignoring()
                .antMatchers("/**/*.html","/webjars/**")
                .antMatchers("/**/favicon.ico")
                .antMatchers("/fonts/**")
                .antMatchers("/css/**")
                .antMatchers("/img/**")
                .antMatchers("/lib/**")
                .antMatchers("/scripts/**")
                .antMatchers("/static-css/**")
                .antMatchers("/static-icons/**")
                .antMatchers("/static-img/**")
                .antMatchers("/static-mock/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()   //禁用csrf
            .authorizeRequests().antMatchers(HttpMethod.GET,"/swagger-resources/configuration/ui",
                "/swagger-resources/configuration/security",
                "/v2/api-docs",
                "/swagger-resources").permitAll()
                //給api開的所有接口不走springsecurity
                .antMatchers(HttpMethod.POST, "/authentication/login",
                        "/authentication/logout","/authentication/techplatLogin","/api/token","/api/sql/create","/api/sql/update").permitAll()
                .antMatchers("/error","/healthCheck").permitAll()
                .antMatchers(HttpMethod.GET,"/api/sql/yarnClusterList","/api/sql/flinksqlEngineList","/api/sql/detail","/api/sql/start"
                        ,"/api/sql/getStartTimeLine","/api/sql/stop","/api/sql/delete").permitAll()
                .anyRequest().authenticated()
                .and()
            .exceptionHandling()
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    @Override
                    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                        response.setCharacterEncoding("utf-8");
                        response.setContentType("text/javascript;charset=utf-8");
                        response.getWriter().print(JSONObject.toJSONString(new ResultDTO(401, "未登錄")));
                    }
                })
                .accessDeniedHandler(new AccessDeniedHandler() {
                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
                        response.setCharacterEncoding("utf-8");
                        response.setContentType("text/javascript;charset=utf-8");
                        response.getWriter().print(JSONObject.toJSONString(new ResultDTO(403, "無權限")));
                    }
                })
                .and()
            .logout()
                .logoutUrl("/authentication/logout")
                .invalidateHttpSession(true)
                .deleteCookies("project-test-sid", "project-sid")
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.setStatus(200);
                        response.setCharacterEncoding("utf-8");
                        response.setContentType("text/javascript;charset=utf-8");
                        response.getWriter().print(JSONObject.toJSONString(ResultDTO.success("註銷成功")));
                    }
                })
                .permitAll();
    }
}
  1. springsecurity的工具類,包含獲取當前登錄的用戶
public class WebSecurityUtil {

    private WebSecurityUtil() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 獲取當前登錄的用戶
     *
     * @return
     */
    public static ProjectUser getUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return (ProjectUser) authentication.getPrincipal();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章