最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security添加驗(yàn)證碼的兩種方式小結(jié)

 更新時(shí)間:2021年10月08日 12:09:18   作者:周杰倫本人  
使用spring security的時(shí)候,框架會(huì)幫我們做賬戶(hù)密碼的驗(yàn)證,但是如我們需要添加一個(gè)驗(yàn)證碼,就需要對(duì)配置文件進(jìn)行修改,這篇文章主要給大家介紹了關(guān)于Spring Security添加驗(yàn)證碼的兩種方式,需要的朋友可以參考下

一、自定義認(rèn)證邏輯

生成驗(yàn)證碼工具

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

添加Kaptcha配置

@Configuration
public class KaptchaConfig {
    @Bean
    Producer kaptcha() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "150");
        properties.setProperty("kaptcha.image.height", "50");
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

生成驗(yàn)證碼文本,放入HttpSession中

根據(jù)驗(yàn)證碼文本生成圖片 通過(guò)IO流寫(xiě)出到前端。

@RestController
public class LoginController {
    @Autowired
    Producer producer;
    @GetMapping("/vc.jpg")
    public void getVerifyCode(HttpServletResponse resp, HttpSession session) throws IOException {
        resp.setContentType("image/jpeg");
        String text = producer.createText();
        session.setAttribute("kaptcha", text);
        BufferedImage image = producer.createImage(text);
        try(ServletOutputStream out = resp.getOutputStream()) {
            ImageIO.write(image, "jpg", out);
        }
    }
    @RequestMapping("/index")
    public String index() {
        return "login success";
    }
    @RequestMapping("/hello")
    public String hello() {
        return "hello spring security";
    }
}

form表單

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    <link  rel="external nofollow"  rel="stylesheet" id="bootstrap-css">
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<style>
    #login .container #login-row #login-column #login-box {
        border: 1px solid #9C9C9C;
        background-color: #EAEAEA;
    }
</style>
<body>
<div id="login">
    <div class="container">
        <div id="login-row" class="row justify-content-center align-items-center">
            <div id="login-column" class="col-md-6">
                <div id="login-box" class="col-md-12">
                    <form id="login-form" class="form" action="/doLogin" method="post">
                        <h3 class="text-center text-info">登錄</h3>
                        <div th:text="${SPRING_SECURITY_LAST_EXCEPTION}"></div>
                        <div class="form-group">
                            <label for="username" class="text-info">用戶(hù)名:</label><br>
                            <input type="text" name="uname" id="username" class="form-control">
                        </div>
                        <div class="form-group">
                            <label for="password" class="text-info">密碼:</label><br>
                            <input type="text" name="passwd" id="password" class="form-control">
                        </div>
                        <div class="form-group">
                            <label for="kaptcha" class="text-info">驗(yàn)證碼:</label><br>
                            <input type="text" name="kaptcha" id="kaptcha" class="form-control">
                            <img src="/vc.jpg" alt="">
                        </div>
                        <div class="form-group">
                            <input type="submit" name="submit" class="btn btn-info btn-md" value="登錄">
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

驗(yàn)證碼圖片地址為我們?cè)贑ontroller中定義的驗(yàn)證碼接口地址。

身份認(rèn)證是AuthenticationProvider的authenticate方法完成,因此驗(yàn)證碼可以在此之前完成:

public class KaptchaAuthenticationProvider extends DaoAuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String kaptcha = req.getParameter("kaptcha");
        String sessionKaptcha = (String) req.getSession().getAttribute("kaptcha");
        if (kaptcha != null && sessionKaptcha != null && kaptcha.equalsIgnoreCase(sessionKaptcha)) {
            return super.authenticate(authentication);
        }
        throw new AuthenticationServiceException("驗(yàn)證碼輸入錯(cuò)誤");
    }
}

配置AuthenticationManager:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    AuthenticationProvider kaptchaAuthenticationProvider() {
        InMemoryUserDetailsManager users = new InMemoryUserDetailsManager(User.builder()
                .username("xiepanapn").password("{noop}123").roles("admin").build());
        KaptchaAuthenticationProvider provider = new KaptchaAuthenticationProvider();
        provider.setUserDetailsService(users);
        return provider;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        ProviderManager manager = new ProviderManager(kaptchaAuthenticationProvider());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/vc.jpg").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/mylogin.html")
                .loginProcessingUrl("/doLogin")
                .defaultSuccessUrl("/index.html")
                .failureForwardUrl("/mylogin.html")
                .usernameParameter("uname")
                .passwordParameter("passwd")
                .permitAll()
                .and()
                .csrf().disable();
    }
}
  1. 配置UserDetailsService提供的數(shù)據(jù)源
  2. 提供AuthenticationProvider實(shí)例并配置UserDetailsService
  3. 重寫(xiě)authenticationManagerBean方法提供一個(gè)自己的ProviderManager并自定義AuthenticationManager實(shí)例。

二、自定義過(guò)濾器

LoginFilter繼承UsernamePasswordAuthenticationFilter 重寫(xiě)attemptAuthentication方法:

public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        String kaptcha = request.getParameter("kaptcha");
        String sessionKaptcha = (String) request.getSession().getAttribute("kaptcha");
        if (!StringUtils.isEmpty(kaptcha) && !StringUtils.isEmpty(sessionKaptcha) && kaptcha.equalsIgnoreCase(sessionKaptcha)) {
            return super.attemptAuthentication(request, response);
        }
        throw new AuthenticationServiceException("驗(yàn)證碼輸入錯(cuò)誤");
    }
}

在SecurityConfig中配置LoginFilter

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication()
                .withUser("javaboy")
                .password("{noop}123")
                .roles("admin");
    }

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

    @Bean
    LoginFilter loginFilter() throws Exception {
        LoginFilter loginFilter = new LoginFilter();
        loginFilter.setFilterProcessesUrl("/doLogin");
        loginFilter.setAuthenticationManager(authenticationManagerBean());
        loginFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/hello"));
        loginFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/mylogin.html"));
        return loginFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/vc.jpg").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/mylogin.html")
                .permitAll()
                .and()
                .csrf().disable();
        http.addFilterAt(loginFilter(),
                UsernamePasswordAuthenticationFilter.class);
    }
}

顯然第二種比較簡(jiǎn)單

總結(jié)

到此這篇關(guān)于Spring Security添加驗(yàn)證碼的兩種方式的文章就介紹到這了,更多相關(guān)Spring Security添加驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA心得分享---return語(yǔ)句的用法

    JAVA心得分享---return語(yǔ)句的用法

    return算是各大語(yǔ)言的常客,基本上都有return語(yǔ)句,那么在JAVA中,return有什么特殊的地方嗎,下面我們來(lái)分析下
    2014-05-05
  • 深入理解Java基礎(chǔ)中的集合框架

    深入理解Java基礎(chǔ)中的集合框架

    Java集合框架(Java Collections Framework, JCF)也稱(chēng)容器,這里可以類(lèi)比 C++中的 STL,在這里主要對(duì)如下部分進(jìn)行源碼分析,及在面試中常見(jiàn)的問(wèn)題,例如,在阿里面試常問(wèn)到的 HashMap和ConcurrentHashMap原理等等,深入源碼分析是面試中必備的技能
    2023-08-08
  • Java面試必考之如何在項(xiàng)目中優(yōu)雅的拋出異常

    Java面試必考之如何在項(xiàng)目中優(yōu)雅的拋出異常

    這篇文章主要為大家詳細(xì)介紹了Java中的幾種異常關(guān)鍵字和異常類(lèi)相關(guān)知識(shí),本文比較適合剛?cè)肟覬ava的小白以及準(zhǔn)備秋招的大佬閱讀,需要的可以收藏一下
    2023-06-06
  • JAVA實(shí)現(xiàn)將磁盤(pán)中所有空文件夾進(jìn)行刪除的代碼

    JAVA實(shí)現(xiàn)將磁盤(pán)中所有空文件夾進(jìn)行刪除的代碼

    這篇文章主要介紹了JAVA實(shí)現(xiàn)將磁盤(pán)中所有空文件夾進(jìn)行刪除的代碼,需要的朋友可以參考下
    2017-06-06
  • Spring Boot項(xiàng)目實(shí)戰(zhàn)之?dāng)r截器與過(guò)濾器

    Spring Boot項(xiàng)目實(shí)戰(zhàn)之?dāng)r截器與過(guò)濾器

    這篇文章主要介紹了Spring Boot項(xiàng)目實(shí)戰(zhàn)之?dāng)r截器與過(guò)濾器,文中給大家詳細(xì)介紹了springboot 攔截器和過(guò)濾器的基本概念,過(guò)濾器的配置,需要的朋友可以參考下
    2018-01-01
  • Java字段初始化的規(guī)律解析

    Java字段初始化的規(guī)律解析

    這篇文章主要介紹了Java字段初始化的規(guī)律解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot Mybatis動(dòng)態(tài)數(shù)據(jù)源切換方案實(shí)現(xiàn)過(guò)程

    SpringBoot Mybatis動(dòng)態(tài)數(shù)據(jù)源切換方案實(shí)現(xiàn)過(guò)程

    這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換方案過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java設(shè)計(jì)模式之外觀(guān)模式的實(shí)現(xiàn)方式

    Java設(shè)計(jì)模式之外觀(guān)模式的實(shí)現(xiàn)方式

    這篇文章主要介紹了Java設(shè)計(jì)模式之外觀(guān)模式的實(shí)現(xiàn)方式,外觀(guān)模式隱藏系統(tǒng)的復(fù)雜性,并向客戶(hù)端提供了一個(gè)客戶(hù)端可以訪(fǎng)問(wèn)系統(tǒng)的接口,這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它向現(xiàn)有的系統(tǒng)添加一個(gè)接口,來(lái)隱藏系統(tǒng)的復(fù)雜性,需要的朋友可以參考下
    2023-11-11
  • 淺談Java內(nèi)省機(jī)制

    淺談Java內(nèi)省機(jī)制

    本文主要介紹了Java內(nèi)省機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java Volatile關(guān)鍵字你真的了解嗎

    Java Volatile關(guān)鍵字你真的了解嗎

    這篇文章主要為大家介紹了Java Volatile關(guān)鍵字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12

最新評(píng)論

万安县| 垫江县| 宜兰县| 策勒县| 新泰市| 鹤壁市| 都昌县| 江华| 高清| 南部县| 句容市| 赫章县| 泗洪县| 惠安县| 辽阳市| 红河县| 唐山市| 册亨县| 毕节市| 东乌| 淮南市| 贡觉县| 义马市| 固阳县| 内黄县| 新干县| 永清县| 奉贤区| 秦皇岛市| 永靖县| 墨脱县| 思茅市| 同德县| 夏津县| 彰武县| 洛扎县| 饶阳县| 祁东县| 吉林市| 澄城县| 五寨县|