国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Spring Boot整合Spring Security

2019-11-08 02:29:31
字體:
來源:轉載
供稿:網友

更多內容請訪問http://lxgandlz.cn

本文講述SPRing Boot整合Spring Security在方法上使用注解實現權限控制,使用自定義UserDetailService,從MySQL中加載用戶信息。使用Security自帶的md5加密,對用戶密碼進行加密。頁面模板采用thymeleaf引擎。 源碼地址:https://github.com/li5454yong/springboot-security.git

1、引入pom依賴

    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.4.4.RELEASE</version>    </parent>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-security</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.security.oauth</groupId>            <artifactId>spring-security-oauth2</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-thymeleaf</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-jpa</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-jdbc</artifactId>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.34</version>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>1.0.15</version>        </dependency>    </dependencies> 這里使用druid連接池,Spring Data Jpa實現數據庫訪問。

2、配置Spring Security

@Configuration@EnableWebMvcSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)//開啟security注解public class WebSecurityConfig extends WebSecurityConfigurerAdapter {    @Bean    @Override    protected AuthenticationManager authenticationManager() throws Exception {        return super.authenticationManager();    }    @Override    protected void configure(HttpSecurity http) throws Exception {        //允許所有用戶訪問"/"和"/home"        http.authorizeRequests()                .antMatchers("/", "/home").permitAll()                //其他地址的訪問均需驗證權限                .anyRequest().authenticated()                .and()                .formLogin()                //指定登錄頁是"/login"                .loginPage("/login")                .defaultSuccessUrl("/hello")//登錄成功后默認跳轉到"/hello"                .permitAll()                .and()                .logout()                .logoutSuccessUrl("/home")//退出登錄后的默認url是"/home"                .permitAll();    }    @Autowired    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {        auth            .userDetailsService(customUserDetailsService())            .passWordEncoder(passwordEncoder());    }    /**     * 設置用戶密碼的加密方式為MD5加密     * @return     */    @Bean    public Md5PasswordEncoder passwordEncoder() {        return new Md5PasswordEncoder();    }    /**     * 自定義UserDetailsService,從數據庫中讀取用戶信息     * @return     */    @Bean    public CustomUserDetailsService customUserDetailsService(){        return new CustomUserDetailsService();    }} 這里只做了基本的配置,設置了登錄url、登錄成功后跳轉的url、退出后跳轉到的url。使用@EnableGlobalMethodSecurity(prePostEnabled = true)這個注解,可以開啟security的注解,我們可以在需要控制權限的方法上面使用@PreAuthorize,@PreFilter這些注解。

3、自定義userDetailService

public class CustomUserDetailsService implements UserDetailsService {    @Autowired  //數據庫服務類    private SUserService suserService;    @Override    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {        //SUser對應數據庫中的用戶表,是最終存儲用戶和密碼的表,可自定義        //本例使用SUser中的email作為用戶名:        SUser user = suserService.findUserByEmail(userName);         if (user == null) {            throw new UsernameNotFoundException("UserName " + userName + " not found");        }        // SecurityUser實現UserDetails并將SUser的Email映射為username        SecurityUser securityUser = new SecurityUser(user);        Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();        authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));        return securityUser;     }} 這里只需要實現UserDetailsService 接口,重寫loadUserByUsername方法,從數據庫中取出用戶信息。最后返回一個UserDetails 實現類。

4、定義錯誤處理配置

@Configurationpublic class ErrorPageConfig {    @Bean    public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){        return new MyCustomizer();    }    private static class MyCustomizer implements EmbeddedServletContainerCustomizer {        @Override        public void customize(ConfigurableEmbeddedServletContainer container) {            container.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/403"));        }    }} 訪問發生錯誤時,跳轉到”/403”.

5、Controller接口

@Controllerpublic class IndexController {    @Resource    private SUserService sUserService;    @RequestMapping("/home")    public String home() {        return "home";    }    @PreAuthorize("hasRole('user')")    @RequestMapping(value = "/admin",method = RequestMethod.GET)    public String toAdmin(){        return "helloAdmin";    }    @RequestMapping("/hello")    public String hello() {        return "hello";    }    @RequestMapping("/login")    public String login(){        return "login";    }    @RequestMapping("/")    public String root() {        return "index";    }    @RequestMapping("/403")    public String error(){        return "403";    }} 

在toAdmin()方法上面使用了@PreAuthorize(“hasRole(‘user’)”),表示訪問這個方法需要擁有user角色。如果希望控制到權限層面,可以使用@PreAuthorize(“haspermission()”)。這里只是用了其中的一個用法,更多的使用方法可以去看官方文檔。需要注意的是,Spring Security默認的角色前綴是”ROLE_”,使用hasRole方法時已經默認加上了,因此我們在數據庫里面的用戶角色應該是“ROLE_user”,在user前面加上”ROLE_”前綴。

6、測試

啟動項目,訪問http://localhost:1130/login

點擊登錄后進入到“/hello”

點擊跳轉到管理員頁面

在后臺的“/admin”這個url對應的方法上面,限制了用戶必須要擁有“user”角色。在數據庫中也設置了登錄的用戶有這個角色。 現在我們修改數據庫中的用戶角色,改為“ROLE_admin”。退出登錄后重新登錄,再次點擊“前往管理員頁面”按鈕,會跳轉到如下頁面。 因為現在沒有了“user”權限,所以訪問的時候拋出了異常,被攔截后重定向到了“/403”。

7、POST方式訪問,錯誤碼403

首先,把“/admin”改為POST請求

    @PreAuthorize("hasRole('user')")    @RequestMapping(value = "/admin",method = RequestMethod.POST)    public String toAdmin(){        return "helloAdmin";    } 

把“前往管理員頁面”按鈕的請求方式從原來的form表達get提交,改為Ajax方式POST提交。至于為什么不是用form的POST提交后面再講。先修改代碼

<body><h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1><!--<form th:action="@{/logout}" method="post">    <input type="submit" value="Sign Out"/></form><form th:action="@{/admin}" method="get">    <input th:type="submit" th:value="前往管理員頁面"/></form>--><a th:href="@{/admin}">前往管理員用戶頁面</a><input th:type="submit" onclick="testPost()" th:value="前往管理員頁面"/></body><script>    function testPost() {        $.ajax({            url:"/admin",            type:'POST',            success:function (data) {            }        });    }</script> 

點擊“前往管理員頁面”按鈕,在調試臺可以看到如下 這是因為框架內部防止CSRF(Cross-site request forgery跨站請求偽造)的發生,限制了除了get以外的大多數方法。

下面說解決辦法: 首先在標簽內添加如下內容。

    <meta name="_csrf" th:content="${_csrf.token}"/>    <meta name="_csrf_hader" th:content="${_csrf.headerName}"/> 

只要添加這個token,后臺就會驗證這個token的正確性,如果正確,則接受post訪問。 然后在ajax代碼中添加以下代碼:

        var token = $('meta[name="_csrf"]').attr("content");        var header = $('meta[name="_csrf_hader"]').attr("content");        $(document).ajaxSend(function(e,xhr,opt){            xhr.setRequestHeader(header,token);        }); 

這樣就可以正常使用POST、DELETE等其他方式來訪問了。 上面說到使用表單的POST方式來提交,通過查看頁面源代碼可以看到 框架在form表單中自動插入了一個隱藏域,value值就是那個token,所以使用form表單來提交POST請求是可以直接通過的,而ajax方式提交的話,需要加上那段代碼。

好了,這篇文章就講到這,后面還會有文章講述REST API風格如何來使用Spring Security來控制權限。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 潜山县| 随州市| 邵东县| 扎囊县| 华阴市| 太白县| 金塔县| 绥江县| 华池县| 安新县| 城固县| 儋州市| 阿尔山市| 康马县| 旺苍县| 中西区| 定南县| 昭通市| 江永县| 桐梓县| 加查县| 永德县| 淮滨县| 英山县| 西平县| 荣成市| 黄冈市| 时尚| 兴业县| 敦化市| 黄骅市| 三门县| 电白县| 策勒县| 太仆寺旗| 姜堰市| 怀宁县| 宜兰县| 横山县| 沂源县| 望都县|