日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Security学习(二)

發布時間:2024/2/28 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Security学习(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下配置基于表單登錄配置

自定義配置登錄頁面

@Override protected void configure(HttpSecurity http) throws Exception {http.formLogin()// 自定義頁面路徑.loginPage("/api/login").and().authorizeRequests()// 允許/api/login的URL訪問 否則瀏覽器頁面將提示重定向次數過多進入死循環.antMatchers("/api/login").permitAll().anyRequest().authenticated(); }

自定義登錄路徑

@Override protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/api/login")// 自定義登錄路徑.loginProcessingUrl("/api/formlogin") .and().authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated(); }

Spring Security 默認表單登錄

public UsernamePasswordAuthenticationFilter() {super(new AntPathRequestMatcher("/login", "POST")); }

可設置loginProcessingUrl屬性來替換默認登錄地址

登錄成功處理

當用戶登錄成功后需要保存用戶登錄數據,比如IP地址,登錄時間等

// 注入SecurityLoginSuccessHandler @Autowired private SecurityLoginSuccessHandler securityLoginSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/api/login")// 自定義登錄成功處理.successHandler(securityLoginSuccessHandler).loginProcessingUrl("/api/formlogin").and().authorizeRequests().antMatchers("/api/login","/static/*").permitAll().anyRequest().authenticated().and().csrf().disable(); }

SecurityLoginSuccessHandler

@Component public class SecurityLoginSuccessHandler implements AuthenticationSuccessHandler {// 重定向跳轉類private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();// 緩存請求路徑,可獲取攔截前的請求路徑private RequestCache requestCache = new HttpSessionRequestCache();@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {System.out.println("登錄成功");// 獲取攔截前請求路徑 并通過RedirectStrategy進行重定向跳轉SavedRequest savedRequest = requestCache.getRequest(request, response);String redirectUrl = savedRequest.getRedirectUrl();// todo do somethingthis.redirectStrategy.sendRedirect(request, response, redirectUrl);} }

登錄失敗處理

跟登錄成功處理一樣 只是實現接口不同而已

@Autowired private SecurityLoginFailHandler securityLoginFailHandler;@Override protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/api/login").successHandler(securityLoginSuccessHandler)// 自定義登錄失敗處理.failureHandler(securityLoginFailHandler).loginProcessingUrl("/api/formlogin").and().authorizeRequests().antMatchers("/api/login", "/static/*").permitAll().anyRequest().authenticated().and().csrf().disable(); }

SecurityLoginFailHandler

@Component public class SecurityLoginFailHandler implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {System.out.println("登錄失敗");// todo do somethingresponse.setCharacterEncoding("UTF-8");response.setContentType("text/json;charset=UTF-8");response.getWriter().write(exception.getMessage());} }

退出登錄

默認是訪問URL/logout將注銷登陸的用戶

自定義配置

@Autowired private SecurityLoginoutHandler securityLoginoutHandler; @Autowired private SecurityLoginoutSuccessHandler securityLoginoutSuccessHandler;@Override protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/api/login").successHandler(securityLoginSuccessHandler).failureHandler(securityLoginFailHandler).loginProcessingUrl("/api/formlogin").and().authorizeRequests().antMatchers("/api/login", "/static/*").permitAll().anyRequest().authenticated().and().logout()// 退出登錄地址.logoutUrl("/logout")// 退出跳轉路徑.logoutSuccessUrl("/api/login")// 默認session失效.invalidateHttpSession(true)// 退出登錄處理.addLogoutHandler(securityLoginoutHandler)// 退出登錄成功處理.logoutSuccessHandler(securityLoginoutSuccessHandler)// 指定退出登錄后需要刪除的cookie名稱,多個cookie之間以逗號分隔。 // .deleteCookies(cookieNamesToClear).and().csrf().disable(); }

SecurityLoginoutHandler

用來執行必要的清理,因而他們不應該拋出錯誤

@Component public class SecurityLoginoutHandler implements LogoutHandler {@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {System.out.println("退出登錄");} }

SecurityLoginoutSuccessHandler

被LogoutFilter在成功注銷后調用,用來進行重定向或者轉發相應的目的地。注意這個接口與LogoutHandler幾乎一樣,但是可以拋出異常。

@Component public class SecurityLoginoutSuccessHandler implements LogoutSuccessHandler {private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {System.out.println("退出登錄成功執行");this.redirectStrategy.sendRedirect(request, response, "/");} }

自定義用戶登錄賬號密碼

WebSecurityConfig

@Autowired private SecurityUserDetailService securityUserDetailService;@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {// 在內存中寫死用戶數據auth.inMemoryAuthentication().withUser("123456").password("123456").roles("USER");// 動態獲取用戶數據auth.userDetailsService(securityUserDetailService); }

SecurityUserDetailService

/*** 自定義UserDetailService** @author Peng*/ @Component public class SecurityUserDetailService implements UserDetailsService {/*** String password; 密碼* String username; 賬戶名* Set<GrantedAuthority> authorities; 角色名* boolean accountNonExpired; 賬戶沒有過期* boolean accountNonLocked; 帳號沒有被鎖定* boolean credentialsNonExpired; 密碼沒有過期* boolean enabled; 是否可用*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 這里寫死的密碼 實際應用中應該從數據庫中獲取 User user = new User(username, "123456", true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("USER"));return user;} }

自定義用戶登錄賬號密碼(密碼加密)

WebSecurityConfig

@Autowired private SecurityUserDetailService securityUserDetailService;@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {// 在內存中寫死用戶數據auth.inMemoryAuthentication().withUser("123456").password("123456").roles("USER");// 動態獲取用戶數據 使用Security加密auth.userDetailsService(securityUserDetailService).passwordEncoder(new BCryptPasswordEncoder());// 配置驗證方式為加密驗證 DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();authenticationProvider.setUserDetailsService(securityUserDetailService);authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());auth.authenticationProvider(authenticationProvider); }

SecurityUserDetailService

/*** 自定義UserDetailService** @author Peng*/ @Component public class SecurityUserDetailService implements UserDetailsService {/*** String password; 密碼* String username; 賬戶名* Set<GrantedAuthority> authorities; 角色名* boolean accountNonExpired; 賬戶沒有過期* boolean accountNonLocked; 帳號沒有被鎖定* boolean credentialsNonExpired; 密碼沒有過期* boolean enabled; 是否可用*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 這里寫死的密碼 實際應用中應該從數據庫中獲取 BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();// 數據庫創建用戶數據時密碼應通過Security加密后保存String password = encoder.encode("123456");System.out.println(password);User user = new User(username, password, true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("USER"));return user;} }

PasswordEncoder

// 密碼加密 String encode(CharSequence rawPassword); // 驗證密碼是否吻合 boolean matches(CharSequence rawPassword, String encodedPassword);

獲取登錄用戶信息

/*** 獲取登錄用戶數據*/ @RequestMapping("/api/getme") @ResponseBody public Object getLoginUser(Authentication authentication) {Map<String, Object> json = new HashMap<>();// 兩種方法json.put("data", SecurityContextHolder.getContext().getAuthentication());json.put("data1", authentication);return json; }

資源權限限制

WebSecurityConfig

.antMatchers("/api/me").hasRole("ADMIN")這樣只要是訪問“api/me”的路徑就會驗證用戶身份,用戶身份必須是ADMIN才允許訪問 表達 描述
hasRole([role])如果當前主體具有指定的角色,則返回true.
hasAnyRole([role1,role2])如果當前的主體有任何提供的角色(給定的作為一個逗號分隔的字符串列表)的話,返回true
hasAuthority([authority])如果當前的主體具有指定的權限,則返回 true.
hasAnyAuthority([authority1,authority2])如果當前的主體有任何提供的角色(給定的作為一個逗號分隔的字符串列表)的話,返回true.
principal允許直接訪問表示當前用戶的主對象
permitAll允許所有用戶訪問
denyAll不允許用戶訪問
isAnonymous()如果當前的主體是一個匿名用戶,則返回true.
isRememberMe()如果當前的主體是一個匿名用戶,則返回true
isAuthenticated()如果用戶不是匿名的,則返回 true
isFullyAuthenticated()如果用戶不是一個匿名的或是一個記住我的用戶返回true
hasPermission(Object target, Object permission)如果用戶已訪問給定權限的提供的目標,則返回true,例如hasPermission(domainObject, 'read')
hasPermission(Object targetId, String targetType, Object permission)如果用戶已訪問給定權限的提供的目標,則返回true,例如hasPermission(1, 'com.example.domain.Message', 'read')

登錄驗證碼

首先得寫一個獲取驗證碼方法,方法能夠生成隨機驗證碼并且把驗證碼存入session供驗證的功能,這里就不寫了

因為Spring Security未提供驗證碼的接口,所以需要我們自己寫一個過濾器處理

VaildCodeFilter 驗證碼校驗過濾器

/*** Security 登錄驗證碼驗證** @author Peng*/ public class VaildCodeFilter extends OncePerRequestFilter {private SecurityLoginFailHandler securityLoginFailHandler;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {// 登錄路徑必須為/api/formlogin才生效if ("/api/formlogin".equals(request.getRequestURI())) {HttpSession session = request.getSession();try {String code = request.getParameter(頁面驗證碼字段);String sessionCode = (String) session.getAttribute(驗證碼sessionId);if (code == null || sessionCode == null) {throw new VaildCodeException("驗證碼不存在");}if (!sessionCode.equals(code)) {throw new VaildCodeException("驗證碼不匹配");}} catch (VaildCodeException e) {securityLoginFailHandler.onAuthenticationFailure(request, response, e);return;}session.removeAttribute(驗證碼sessionId);}filterChain.doFilter(request, response);}public void setSecurityLoginFailHandler(SecurityLoginFailHandler securityLoginFailHandler) {this.securityLoginFailHandler = securityLoginFailHandler;} } 最后在WebSecurityConfig configure中配置
@Overrideprotected void configure(HttpSecurity http) throws Exception {// 在UsernamePasswordAuthenticationFilter過濾器前添加自定義驗證碼過濾器VaildCodeFilter vaildCodeFilter = new VaildCodeFilter();vaildCodeFilter.setSecurityLoginFailHandler(securityLoginFailHandler);http.addFilterBefore(vaildCodeFilter, UsernamePasswordAuthenticationFilter.class);http.formLogin().loginPage("/api/login").successHandler(securityLoginSuccessHandler).failureHandler(securityLoginFailHandler).loginProcessingUrl("/api/formlogin");http.authorizeRequests().antMatchers("/api/login", "/static/*", "/api/codeImg").permitAll().antMatchers("/api/me").hasRole("ADMIN").anyRequest().authenticated();http.logout().logoutUrl("/logout").logoutSuccessUrl("/api/login").invalidateHttpSession(true).addLogoutHandler(securityLoginoutHandler).logoutSuccessHandler(securityLoginoutSuccessHandler);// 指定退出登錄后需要刪除的cookie名稱,多個cookie之間以逗號分隔。 // .deleteCookies(cookieNamesToClear)http.csrf().disable();}

總結

以上是生活随笔為你收集整理的Spring Security学习(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。