<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          精通 Spring Boot 系列文(12)

          共 4632字,需瀏覽 10分鐘

           ·

          2020-07-29 00:31

          閱讀全文,約 18?分鐘


          精通 Spring Boot 系列文(1)
          精通 Spring Boot 系列文(2)
          精通 Spring Boot 系列文(2)
          精通 Spring Boot 系列文(4)
          精通 Spring Boot 系列文(5)
          精通 Spring Boot 系列文(6)
          精通 Spring Boot 系列文(7)
          精通 Spring Boot 系列文(8)
          精通 Spring Boot 系列文(9)
          精通 Spring Boot 系列文(10)
          精通 Spring Boot 系列文(11)

          Spring Boot 的安全管理

          1、Spring Security 是啥?

          Spring Security 是 Spring 的一個安全模塊,它很強(qiáng)大,但使用特別復(fù)雜。在安全管理這個領(lǐng)域,之前還有一個 Shiro 是比較受歡迎的,對于大部分的應(yīng)用,Shiro 用得也比較成熟。Spring Boot 現(xiàn)在為 Spring Security 提供了自動化配置方案,用起來非常方便,所以大家慢慢就選擇使用了 Spring Security 了。

          最近,很多安全管理技術(shù)棧的組合長這樣的:Spring Boot/Spring Cloud + Spring Security。

          安全框架有兩大主要操作:認(rèn)證(Authentication)和授權(quán)(Authorization)。

          2、Spring Security 簡單使用

          如何配置 Spring Security?非常簡單,我們直接在類上繼承 WebSecurityConfigurerAdapter 適配器即可,然后再用 @EnableWebSecurity 注解,再重寫
          configure() 方法來配置對應(yīng)的安全信息。

          我們還需要了解兩個事情:用戶認(rèn)證、用戶授權(quán)

          2.1 用戶認(rèn)證

          主要通過在?

          configureGlobal(AuthenticationManagerBuilder amb) 方法完成用戶認(rèn)證,然后通過?

          AuthenticationManagerBuilder 的 inMemoryAuthentication() 方法來添加用戶,和用戶的權(quán)限。

          2.2 用戶授權(quán)

          主要通過 configure(HttpSecurity hs) 方法,完成用戶授權(quán),然后 HttpSecurity 的 authorizeRequests() 方法能設(shè)置多個 macher 節(jié)點(diǎn)來聲明執(zhí)行順序,這樣用戶就能夠訪問多個 URL 模式了。

          當(dāng)你匹配了對應(yīng)的請求路徑之后,然后再執(zhí)行安全處理。

          Spring Security 的安全處理方法:

          • anyRequest:匹配所有路徑

          • access:可以訪問,當(dāng) Spring EL 的結(jié)果為 ture

          • anonymous:匿名可訪問

          • denyAll:用戶不能訪問

          • fullyAuthenticated:用戶完全認(rèn)證可訪問

          • hasAnyAuthority:參數(shù)代表權(quán)限,列出來任何一個的可訪問

          • hasAnyRole:參數(shù)代表角色,列出來任何一個的可訪問

          • hasAuthority:參數(shù)代表權(quán)限,列出來的可訪問

          • hasIpAddress:參數(shù)代表 IP 地址,匹配的可訪問

          • hasRole:參數(shù)角色,列出來的可訪問

          • permitAll:用戶可以任意訪問

          • rememberMe:允許通過 remember-me 登錄的用戶訪問

          • authenticated:用戶登錄后可訪問

          3、Spring Security 簡單案例

          1)編輯 pom.xml 文件

          <project?xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          ?????????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">

          ????<modelVersion>4.0.0modelVersion>

          ????<groupId>com.nxgroupId>
          ????<artifactId>springbootdataartifactId>
          ????<version>1.0-SNAPSHOTversion>

          ????<parent>
          ????????<groupId>org.springframework.bootgroupId>
          ????????<artifactId>spring-boot-starter-parentartifactId>
          ????????<version>2.2.6.RELEASEversion>
          ????????<relativePath/>
          ????parent>

          ????<properties>
          ????????<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
          ????????<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
          ????????<java.version>1.8java.version>
          ????properties>

          ??<dependencies>

          ??????
          ??????<dependency>
          ????????<groupId>org.springframework.bootgroupId>
          ????????<artifactId>spring-boot-starter-webartifactId>
          ????dependency>

          ??????
          ??????<dependency>
          ????????<groupId>org.springframework.bootgroupId>
          ????????<artifactId>spring-boot-starter-thymeleafartifactId>
          ????dependency>

          ????
          ??????<dependency>
          ????????<groupId>org.springframework.bootgroupId>
          ????????<artifactId>spring-boot-starter-securityartifactId>
          ????dependency>

          ????<dependency>
          ??????<groupId>junitgroupId>
          ??????<artifactId>junitartifactId>
          ??????<scope>testscope>
          ????dependency>
          ??dependencies>
          project>

          2)創(chuàng)建 NXPasswordEncoder 認(rèn)證邏輯類

          public?class?NXPasswordEncoder?implements?PasswordEncoder{

          ????@Override
          ????public?String?encode(CharSequence?arg0)?{
          ????????return?arg0.toString();
          ????}

          ????@Override
          ????public?boolean?matches(CharSequence?arg0,?String?arg1)?{
          ????????return?arg1.equals(arg0.toString());
          ????}
          }

          3)創(chuàng)建 AppSecurityConfigurer 密碼器

          目前,Spring Security 的密碼存儲格式為:{id}encodedPassword,其中 id 是用來找到對應(yīng)的 PasswordEncoder,encodedPassword 用來指原始密碼經(jīng)過加密之后的密碼。當(dāng)我們想自定義密碼器,必須實(shí)現(xiàn) PasswordEncoder 接口。

          @Configuration
          public?class?AppSecurityConfigurer?extends?WebSecurityConfigurerAdapter{

          ????//?注入認(rèn)證處理類,處理不同用戶跳轉(zhuǎn)到不同的頁面
          ????@Autowired
          ????AppAuthenticationSuccessHandler?appAuthenticationSuccessHandler;

          ????//?用戶授權(quán)操作?
          ????@Override
          ????protected?void?configure(HttpSecurity?http)?throws?Exception?{

          ????????http.authorizeRequests()
          ????????//?需要過濾靜態(tài)資源
          ????????.antMatchers("/login","/css/**","/js/**","/img/*").permitAll()?
          ????????.antMatchers("/",?"/home").hasRole("USER")
          ????????.antMatchers("/admin/**").hasAnyRole("ADMIN",?"DBA")
          ????????.anyRequest().authenticated()
          ????????.and()
          ????????.formLogin().loginPage("/login").successHandler(appAuthenticationSuccessHandler)
          ????????.usernameParameter("loginName").passwordParameter("password")
          ????????.and()
          ????????.logout().permitAll()
          ????????.and()
          ????????.exceptionHandling().accessDeniedPage("/accessDenied");
          ????}

          ????//?用戶認(rèn)證操作
          ????@Autowired
          ????public?void?configureGlobal(AuthenticationManagerBuilder?auth)?throws?Exception?{

          ????????//?需要密碼編碼器
          ????????auth.inMemoryAuthentication().passwordEncoder(new?NXPasswordEncoder()).withUser("nx").password("888888").roles("USER");
          ???????auth.inMemoryAuthentication().passwordEncoder(new?NXPasswordEncoder()).withUser("admin").password("admin").roles("ADMIN","DBA");
          ????}
          }

          4)創(chuàng)建 AppAuthenticationSuccessHandler 認(rèn)證成功處理類

          @Component
          public?class?AppAuthenticationSuccessHandler?extends?SimpleUrlAuthenticationSuccessHandler{

          ????//?通過?RedirectStrategy?對象負(fù)責(zé)所有重定向事務(wù)
          ????private?RedirectStrategy?redirectStrategy?=?new?DefaultRedirectStrategy();

          ????//?重寫?handle?方法,通過?RedirectStrategy?對象重定向到指定的?url
          ????@Override
          ????protected?void?handle(HttpServletRequest?request,?HttpServletResponse?response,
          ????????????Authentication?authentication)

          ????????????throws?IOException?
          {
          ????????//?通過?determineTargetUrl?方法返回需要跳轉(zhuǎn)的?url?
          ????????String?targetUrl?=?determineTargetUrl(authentication);
          ????????redirectStrategy.sendRedirect(request,?response,?targetUrl);
          ????}

          ????//?從 Authentication 對象中提取角色提取當(dāng)前登錄用戶的角色,并根據(jù)其角色返回適當(dāng)?shù)?URL。
          ????protected?String?determineTargetUrl(Authentication?authentication)?{
          ????????String?url?=?"";

          ????????//?獲取當(dāng)前登錄用戶的角色權(quán)限集合
          ????????Collection?authorities?=?authentication.getAuthorities();

          ????????List?roles?=?new?ArrayList();

          ????????for?(GrantedAuthority?a?:?authorities)?{
          ????????????roles.add(a.getAuthority());
          ????????}

          ????????//?判斷不同角色跳轉(zhuǎn)到不同的url
          ????????if?(isAdmin(roles))?{
          ????????????url?=?"/admin";
          ????????}?else?if?(isUser(roles))?{
          ????????????url?=?"/home";
          ????????}?else?{
          ????????????url?=?"/accessDenied";
          ????????}
          ????????System.out.println("url?=?"?+?url);
          ????????return?url;
          ????}

          ????private?boolean?isUser(List?roles)?{
          ????????if?(roles.contains("ROLE_USER"))?{
          ????????????return?true;
          ????????}
          ????????return?false;
          ????}

          ????private?boolean?isAdmin(List?roles)?{
          ????????if?(roles.contains("ROLE_ADMIN"))?{
          ????????????return?true;
          ????????}
          ????????return?false;
          ????}

          ????public?void?setRedirectStrategy(RedirectStrategy?redirectStrategy)?{
          ????????this.redirectStrategy?=?redirectStrategy;
          ????}

          ????protected?RedirectStrategy?getRedirectStrategy()?{
          ????????return?redirectStrategy;
          ????}
          }

          5)創(chuàng)建 NXController 控制器

          @Controller
          public?class?NXController?{

          ????@RequestMapping("/")
          ????public?String?index()?{
          ????????return?"index";
          ????}

          ?????@RequestMapping(value?=?"/login")
          ????public?String?login()?{
          ????????return?"login";
          ????}

          ????@RequestMapping("/home")
          ????public?String?homePage(Model?model)?{
          ????????model.addAttribute("user",?getUsername());
          ????????model.addAttribute("role",?getAuthority());
          ????????return?"home";
          ????}

          ????@RequestMapping(value?=?"/admin")
          ????public?String?adminPage(Model?model)?{
          ????????model.addAttribute("user",?getUsername());
          ????????model.addAttribute("role",?getAuthority());
          ????????return?"admin";
          ????}

          ????@RequestMapping(value?=?"/dba")
          ????public?String?dbaPage(Model?model)?{
          ????????model.addAttribute("user",?getUsername());
          ????????model.addAttribute("role",?getAuthority());
          ????????return?"dba";
          ????}

          ????@RequestMapping(value?=?"/accessDenied")
          ????public?String?accessDeniedPage(Model?model)?{
          ????????model.addAttribute("user",?getUsername());
          ????????model.addAttribute("role",?getAuthority());
          ????????return?"accessDenied";
          ????}


          ???@RequestMapping(value="/logout")
          ????public?String?logoutPage?(HttpServletRequest?request,?HttpServletResponse?response)?{
          ???????//?Authentication是一個接口,表示用戶認(rèn)證信息
          ????????Authentication?auth?=?SecurityContextHolder.getContext().getAuthentication();
          ????????//?如果用戶認(rèn)知信息不為空,注銷
          ????????if?(auth?!=?null){????
          ????????????new?SecurityContextLogoutHandler().logout(request,?response,?auth);
          ????????}
          ????????//?重定向到login頁面
          ????????return?"redirect:/login?logout";
          ????}

          ????private?String?getUsername(){
          ????????//?從SecurityContex中獲得Authentication對象代表當(dāng)前用戶的信息
          ????????String?username?=?SecurityContextHolder.getContext().getAuthentication().getName();
          ????????System.out.println("username?=?"?+?username);
          ????????return?username;
          ????}

          ????private?String?getAuthority(){
          ????????//?獲得Authentication對象,表示用戶認(rèn)證信息。
          ????????Authentication?authentication?=?SecurityContextHolder.getContext().getAuthentication();
          ????????List?roles?=?new?ArrayList();

          ????????for?(GrantedAuthority?a?:?authentication.getAuthorities())?{
          ????????????roles.add(a.getAuthority());
          ????????}
          ????????System.out.println("role?=?"?+?roles);
          ????????return?roles.toString();
          ????}
          }

          最后,大家可以找一套前端頁面,測試一下即可,非常簡單的。

          未完待續(xù),等我下一篇?~~~

          Java后端編程

          更多Java推文,關(guān)注公眾號

          瀏覽 53
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产偷人免费视频 | 免费免草视频在线播放 | 男人天堂五月天 | 自拍偷拍一区 | 国产免费AV在线观看 |