spring secuity登录不跳转问题解决及自定义密码分析

之前用spring security写一个登录demo的时候,一直遇到一个问题,在登录页面登录之后,一直不进行跳转,一直在登录界面,然后找了好久,才找到原因。
先来讲我遇到这个问题的解决办法。
先进行配置html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
    <input name="username" type="text"/>用户名
    <br>
    <input name="password"  type="text" />密码
    <br>
    <!--在这里遇到了一个问题,因为登录的时候我最开始传的是${_csrf.getHeaderName()} ,
    然后我看了CsrfFilter类的doFilterInternal方法后才发现${_csrf.parameterName}
    才会有后面的验证,然后我把这里改了之后就成功了
    但是我看源码里面其实也有获取getHeadName()这个方法,没理解到这里-->
    <input th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
    <input type="submit"></input>
</form>
</body>
</html>

在csrfFilter里,每次登录都会有一个验证

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		request.setAttribute(HttpServletResponse.class.getName(), response);
		CsrfToken csrfToken = this.tokenRepository.loadToken(request);
		boolean missingToken = (csrfToken == null);
		if (missingToken) {
			csrfToken = this.tokenRepository.generateToken(request);
			this.tokenRepository.saveToken(csrfToken, request, response);
		}
		request.setAttribute(CsrfToken.class.getName(), csrfToken);
		request.setAttribute(csrfToken.getParameterName(), csrfToken);
		if (!this.requireCsrfProtectionMatcher.matches(request)) {
			if (this.logger.isTraceEnabled()) {
				this.logger.trace("Did not protect against CSRF since request did not match "
						+ this.requireCsrfProtectionMatcher);
			}
			filterChain.doFilter(request, response);
			return;
		}
		String actualToken = request.getHeader(csrfToken.getHeaderName());
		if (actualToken == null) {
			actualToken = request.getParameter(csrfToken.getParameterName());
		}
		if (!csrfToken.getToken().equals(actualToken)) {
			this.logger.debug(
					LogMessage.of(() -> "Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)));
			AccessDeniedException exception = (!missingToken) ? new InvalidCsrfTokenException(csrfToken, actualToken)
					: new MissingCsrfTokenException(actualToken);
			this.accessDeniedHandler.handle(request, response, exception);
			return;
		}
		filterChain.doFilter(request, response);
	}

在String actualToken = request.getHeader(csrfToken.getHeaderName());
if (actualToken == null) {
actualToken = request.getParameter(csrfToken.getParameterName());
}
这里我不是很清楚为什么取不到request.getHeader(csrfToken.getHeaderName());
了解的大佬麻烦告诉下

然后后面就是

@Configuration //之前写过配置类的作用 这里就是相当于定义为一个Spring容器
@EnableWebSecurity //简单理解为默认开启crsf防护
public class MyConfig extends WebSecurityConfigurerAdapter {
    Logger log = LoggerFactory.getLogger(MyConfig.class);
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println(new BCryptPasswordEncoder().encode("111"));
        log.info("{}值",new BCryptPasswordEncoder().encode("111"));
        http.
        authorizeRequests() .antMatchers("/hi","/success","/login.html").permitAll().
        anyRequest().authenticated().
        and().
        //登录页面
        formLogin().loginPage("views/login.html").permitAll().
        //这里的登录确认页面,这里需要和html里面form表单里面的action一样
        loginProcessingUrl("/login").permitAll().
             //登录成功后固定跳转的页面
                defaultSuccessUrl("/ok",true).permitAll().
                //这里是失败后,可以获取失败的原因的地方
                failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        e.printStackTrace();
                    }
                }).permitAll().
        and().
        csrf()  .csrfTokenRepository(new HttpSessionCsrfTokenRepository());
        /*如果实在解决不了登录那个问题可以用
        csrf().disable();
        或者
        csrf().ignoringAntMatchers("/login") 
        都可以登录成功
*/
    }

	//这里主要是对密码进行加密
   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //auth.userDetailsService().passwordEncoder();
        /*我在这里也遇到一个问题,如果这里只写了user和password的话是会出错
       然后我看了inMemoryAuthentication的源码之后,发现有6个还是7个必输项
       但是如果只有2个参数的话,是会启动报错的,但是如果有3个参数就不会,
       启动不会报错,感觉和官方的解释有点矛盾
       */
        auth.inMemoryAuthentication().withUser("111").password(new BCryptPasswordEncoder().encode("111")).roles("admin").authorities("1");
    }
	/*
	加密这里大致说一下 现在一般常见的就是md5,md5虽然很快但是很容易被破解
	比如说字典啊,彩虹表之类的。所以一般情况下就需要加salt(加盐)。
	加盐的大致理解可以为在原密码上加上固定盐或者随机盐
	加固定盐的坏处显而易见,也会很容易被破解。
	那么加随机盐的话,那么随机盐是怎么生成的,还有这个随机盐是保存在哪里,
	随机盐的生成其实可以取一些逻辑,比如你的账户中,你的用户名中,然后把
	生成的随机盐放放在自己的密码中,比如放在密码的最后面。
	如果用户登录的话,从数据库取到有随机盐的密文密码,然后把密文密码进行分解
	,把盐那到后在和输入的密码进行组合后进行加密后在对比
	*/
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

如果本篇内容有问题,请第一时间联系我,我会第一时间修改。
谢谢大家。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值