成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring Security配置JSON登錄

adam1q84 / 1804人閱讀

摘要:準備工作基本的配置就不說了,網(wǎng)上一堆例子,只要弄到普通的表單登錄和自定義就可以。是基于的,因此才能在基于前起作用。這樣我們沒有破壞原有的獲取流程,還是可以重用父類原有的方法來處理表單登錄。

spring security用了也有一段時間了,弄過異步和多數(shù)據(jù)源登錄,也看過一點源碼,最近弄rest,然后順便搭oauth2,前端用json來登錄,沒想到spring security默認居然不能獲取request中的json數(shù)據(jù),谷歌一波后只在stackoverflow找到一個回答比較靠譜,還是得要重寫filter,于是在這里填一波坑。

準備工作

基本的spring security配置就不說了,網(wǎng)上一堆例子,只要弄到普通的表單登錄和自定義UserDetailsService就可以。因為需要重寫Filter,所以需要對spring security的工作流程有一定的了解,這里簡單說一下spring security的原理。

spring security 是基于javax.servlet.Filter的,因此才能在spring mvc(DispatcherServlet基于Servlet)前起作用。

UsernamePasswordAuthenticationFilter:實現(xiàn)Filter接口,負責攔截登錄處理的url,帳號和密碼會在這里獲取,然后封裝成Authentication交給AuthenticationManager進行認證工作

Authentication:貫穿整個認證過程,封裝了認證的用戶名,密碼和權(quán)限角色等信息,接口有一個boolean isAuthenticated()方法來決定該Authentication認證成功沒;

AuthenticationManager:認證管理器,但本身并不做認證工作,只是做個管理者的角色。例如默認實現(xiàn)ProviderManager會持有一個AuthenticationProvider數(shù)組,把認證工作交給這些AuthenticationProvider,直到有一個AuthenticationProvider完成了認證工作。

AuthenticationProvider:認證提供者,默認實現(xiàn),也是最常使用的是DaoAuthenticationProvider。我們在配置時一般重寫一個UserDetailsService來從數(shù)據(jù)庫獲取正確的用戶名密碼,其實就是配置了DaoAuthenticationProviderUserDetailsService屬性,DaoAuthenticationProvider會做帳號和密碼的比對,如果正常就返回給AuthenticationManager一個驗證成功的Authentication

UsernamePasswordAuthenticationFilter源碼里的obtainUsername和obtainPassword方法只是簡單地調(diào)用request.getParameter方法,因此如果用json發(fā)送用戶名和密碼會導致DaoAuthenticationProvider檢查密碼時為空,拋出BadCredentialsException

/**
     * Enables subclasses to override the composition of the password, such as by
     * including additional values and a separator.
     * 

* This might be used for example if a postcode/zipcode was required in addition to * the password. A delimiter such as a pipe (|) should be used to separate the * password and extended value(s). The AuthenticationDao will need to * generate the expected password in a corresponding manner. *

* * @param request so that request attributes can be retrieved * * @return the password that will be presented in the Authentication * request token to the AuthenticationManager */ protected String obtainPassword(HttpServletRequest request) { return request.getParameter(passwordParameter); } /** * Enables subclasses to override the composition of the username, such as by * including additional values and a separator. * * @param request so that request attributes can be retrieved * * @return the username that will be presented in the Authentication * request token to the AuthenticationManager */ protected String obtainUsername(HttpServletRequest request) { return request.getParameter(usernameParameter); }
重寫UsernamePasswordAnthenticationFilter

上面UsernamePasswordAnthenticationFilter的obtainUsername和obtainPassword方法的注釋已經(jīng)說了,可以讓子類來自定義用戶名和密碼的獲取工作。但是我們不打算重寫這兩個方法,而是重寫它們的調(diào)用者attemptAuthentication方法,因為json反序列化畢竟有一定消耗,不會反序列化兩次,只需要在重寫的attemptAuthentication方法中檢查是否json登錄,然后直接反序列化返回Authentication對象即可。這樣我們沒有破壞原有的獲取流程,還是可以重用父類原有的attemptAuthentication方法來處理表單登錄。

/**
 * AuthenticationFilter that supports rest login(json login) and form login.
 * @author chenhuanming
 */
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        //attempt Authentication when Content-Type is json
        if(request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
                ||request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){

            //use jackson to deserialize json
            ObjectMapper mapper = new ObjectMapper();
            UsernamePasswordAuthenticationToken authRequest = null;
            try (InputStream is = request.getInputStream()){
                AuthenticationBean authenticationBean = mapper.readValue(is,AuthenticationBean.class);
                authRequest = new UsernamePasswordAuthenticationToken(
                        authenticationBean.getUsername(), authenticationBean.getPassword());
            }catch (IOException e) {
                e.printStackTrace();
                authRequest = new UsernamePasswordAuthenticationToken(
                        "", "");
            }finally {
                setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            }
        }

        //transmit it to UsernamePasswordAuthenticationFilter
        else {
            return super.attemptAuthentication(request, response);
        }
    }
}

封裝的AuthenticationBean類,用了lombok簡化代碼(lombok幫我們寫getter和setter方法而已)

@Getter
@Setter
public class AuthenticationBean {
    private String username;
    private String password;
}
WebSecurityConfigurerAdapter配置

重寫Filter不是問題,主要是怎么把這個Filter加到spring security的眾多filter里面。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors().and()
            .antMatcher("/**").authorizeRequests()
            .antMatchers("/", "/login**").permitAll()
            .anyRequest().authenticated()
            //這里必須要寫formLogin(),不然原有的UsernamePasswordAuthenticationFilter不會出現(xiàn),也就無法配置我們重新的UsernamePasswordAuthenticationFilter
            .and().formLogin().loginPage("/")
            .and().csrf().disable();

    //用重寫的Filter替換掉原有的UsernamePasswordAuthenticationFilter
    http.addFilterAt(customAuthenticationFilter(),
    UsernamePasswordAuthenticationFilter.class);
}

//注冊自定義的UsernamePasswordAuthenticationFilter
@Bean
CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
    CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
    filter.setAuthenticationSuccessHandler(new SuccessHandler());
    filter.setAuthenticationFailureHandler(new FailureHandler());
    filter.setFilterProcessesUrl("/login/self");

    //這句很關(guān)鍵,重用WebSecurityConfigurerAdapter配置的AuthenticationManager,不然要自己組裝AuthenticationManager
    filter.setAuthenticationManager(authenticationManagerBean());
    return filter;
}

題外話,如果搭自己的oauth2的server,需要讓spring security oauth2共享同一個AuthenticationManager(源碼的解釋是這樣寫可以暴露出這個AuthenticationManager,也就是注冊到spring ioc)

@Override
@Bean // share AuthenticationManager for web and oauth
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

至此,spring security就支持表單登錄和異步json登錄了。

參考來源

stackoverflow的問答

其它鏈接

我的簡書

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67520.html

相關(guān)文章

  • Spring Security 實現(xiàn)用戶授權(quán)

    摘要:實現(xiàn)用戶認證本次,我們通過的授權(quán)機制,實現(xiàn)用戶授權(quán)。啟用注解默認的是不進行授權(quán)注解攔截的,添加注解以啟用注解的全局方法攔截。角色該角色對應菜單示例用戶授權(quán)代碼體現(xiàn)授權(quán)思路遍歷當前用戶的菜單,根據(jù)菜單中對應的角色名進行授權(quán)。 引言 上一次,使用Spring Security與Angular實現(xiàn)了用戶認證。Spring Security and Angular 實現(xiàn)用戶認證 本次,我們通過...

    xfee 評論0 收藏0
  • spring security安全防護

    摘要:發(fā)現(xiàn)無效后,會返回一個的訪問拒絕,不過可以通過配置類處理異常來定制行為。惡意用戶可能提交一個有效的文件,并使用它執(zhí)行攻擊。默認是禁止進行嗅探的。 前言 xss攻擊(跨站腳本攻擊):攻擊者在頁面里插入惡意腳本代碼,用戶瀏覽該頁面時,腳本代碼就會執(zhí)行,達到攻擊者的目的。原理就是:攻擊者對含有漏洞的服務器注入惡意代碼,引誘用戶瀏覽受到攻擊的服務器,并打開相關(guān)頁面,執(zhí)行惡意代碼。xss攻擊方式...

    tuantuan 評論0 收藏0
  • Spring Security

    摘要:框架具有輕便,開源的優(yōu)點,所以本譯見構(gòu)建用戶管理微服務五使用令牌和來實現(xiàn)身份驗證往期譯見系列文章在賬號分享中持續(xù)連載,敬請查看在往期譯見系列的文章中,我們已經(jīng)建立了業(yè)務邏輯數(shù)據(jù)訪問層和前端控制器但是忽略了對身份進行驗證。 重拾后端之Spring Boot(四):使用JWT和Spring Security保護REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 評論0 收藏0
  • spring security登錄、登出、認證異常返回值的自定義實現(xiàn)

    摘要:在整個學習過程中,我最關(guān)心的內(nèi)容有號幾點,其中一點是前后端分離的情況下如何不跳轉(zhuǎn)頁面而是返回需要的返回值。登錄成功,不跳轉(zhuǎn)頁面,返回自定義返回值在官方文檔第節(jié),有這么一段描述要進一步控制目標,可以使用屬性作為的替代。 在整個學習過程中,我最關(guān)心的內(nèi)容有號幾點,其中一點是【前后端分離的情況下如何不跳轉(zhuǎn)頁面而是返回需要的返回值】。下面就說一下學習結(jié)果,以xml配置位李。 登錄成功,不跳轉(zhuǎn)頁...

    mushang 評論0 收藏0
  • 使用JWT保護你的Spring Boot應用 - Spring Security實戰(zhàn)

    摘要:創(chuàng)建應用有很多方法去創(chuàng)建項目,官方也推薦用在線項目創(chuàng)建工具可以方便選擇你要用的組件,命令行工具當然也可以。對于開發(fā)人員最大的好處在于可以對應用進行自動配置。 使用JWT保護你的Spring Boot應用 - Spring Security實戰(zhàn) 作者 freewolf 原創(chuàng)文章轉(zhuǎn)載請標明出處 關(guān)鍵詞 Spring Boot、OAuth 2.0、JWT、Spring Security、SS...

    wemall 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<