spring boot+spring security+Thymeleaf 返回认证失败指定的信息

13 篇文章 1 订阅

注意:网上找了很久,一直几乎都是“同样一篇文章”,觉得这些人吧,很坑。。所以,经过我不懈努力,找了很久的资料。终于解决了我的问题:

其余网站说明了

页面需要定义这个。原因是说从session获取的错误信息

<p th:if="${param.error}" th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message} " class="bg-danger"></p> 

详细的代码如下:

1.pom.xml

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity4</artifactId>
		</dependency>
		<dependency>
			<groupId>nz.net.ultraq.thymeleaf</groupId>
			<artifactId>thymeleaf-layout-dialect</artifactId>
			<version>2.2.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.15</version>
			<scope>runtime</scope>
		</dependency>

		<!--添加jsp依赖
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>-->

		<!-- 添加fastjson 支持 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.39</version>
		</dependency>

		<!-- Lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.18</version>
			<scope>provided</scope>
		</dependency>

		<!-- PageHelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.1.2</version>
		</dependency>

	</dependencies>

2.配置

package org.atm.vl.conf;

import org.atm.vl.service.impl.sys.UserServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


/**
 * Created by on 2019/5/8 11:39
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //    @Autowired
//    private UserServiceImpl userService;
    @Bean
    UserDetailsService userService() { //注册UserDetailsService 的bean
        return new UserServiceImpl();
    }

//    public static void main(String[] args) {
//            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//            //加密"0"
//            String encode = bCryptPasswordEncoder.encode("123456");
//            System.out.println(encode);
//            //结果:$2a$10$/eEV4X7hXPzYGzOLXfCizu6h7iRisp7I116wPA3P9uRcHAKJyY4TK
//        //
//    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService()).passwordEncoder(new BCryptPasswordEncoder()); //user Details Service验证
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .antMatchers(new String[]{"/js/**", "/css/**", "/img/**", "/images/**", "/fonts/**", "/**/favicon.ico"}).permitAll()//
                .and()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/login?error")
                .permitAll() //登录页面用户任意访问
                .and()
                .logout().permitAll(); //注销行为任意访问

        // 设置可以iframe访问
        http.headers().frameOptions().sameOrigin();
    }
}
package org.atm.vl.service.impl.sys;

import org.atm.vl.conf.MyUsernameNotFoundException;
import org.atm.vl.mapper.UserMapper;
import org.atm.vl.service.sys.UserService;
import org.atm.vl.vo.sys.RoleVO;
import org.atm.vl.vo.sys.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
public class UserServiceImpl implements UserDetailsService, UserService { //自定义UserDetailsService 接口

    @Autowired
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) { //重写loadUserByUsername 方法获得 userdetails 类型用户

        UserVO user = userMapper.findByUserName(username);
        /*if (user == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }*/
        if (user == null) {
            throw new MyUsernameNotFoundException("用户名不存在");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //用于添加用户的权限。只要把用户权限添加到authorities 就万事大吉。
        for (RoleVO role : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(), authorities);
    }
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="keywords" content=""/>
    <script type="application/x-javascript"> addEventListener("load", function () {
        setTimeout(hideURLbar, 0);
    }, false);
    function hideURLbar() {
        window.scrollTo(0, 1);
    } </script>
    <title>登录页面</title>
    <!-- Bootstrap Core CSS -->
    <link href="/static/css/bootstrap.css" rel='stylesheet' type='text/css'/>

    <!-- Custom CSS -->
    <link href="/static/css/style.css" rel='stylesheet' type='text/css'/>

    <!-- font-awesome icons CSS-->
    <link href="/static/css/font-awesome.css" rel="stylesheet">
    <!-- //font-awesome icons CSS-->

    <!-- side nav css file -->
    <link href='/static/css/SidebarNav.min.css' media='all' rel='stylesheet' type='text/css'/>
    <!-- side nav css file -->

    <!-- js-->
    <script src="/static/js/jquery-1.11.1.min.js"></script>
    <script src="/static/js/modernizr.custom.js"></script>

    <!--webfonts-->
    <link href="http://fonts.googleapis.com/css?family=PT+Sans:400,400i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext"
          rel="stylesheet">
    <!--//webfonts-->

    <!-- Metis Menu -->
    <script src="/static/js/metisMenu.min.js"></script>
    <script src="/static/js/custom.js"></script>
    <link href="/static/css/custom.css" rel="stylesheet">
    <!--//Metis Menu -->
    <!-- //pie-chart --><!-- index page sales reviews visitors pie chart -->

    <!-- requried-jsfiles-for owl -->
    <link href="/static/css/owl.carousel.css" rel="stylesheet">
    <script src="/static/js/owl.carousel.js"></script>
    <!-- //requried-jsfiles-for owl -->
</head>


<body class="cbp-spmenu-push">
<div class="main-content">
    <div id="page-wrapper">
        <div class="main-page login-page ">
            <h2 class="title1">Login</h2>
            <div class="widget-shadow">
                <div class="login-body">
                                       <div class="container">

                        <div class="starter-template">
                            <p th:if="${param.logout}" class="bg-warning">已成功注销</p><!-- 1 -->
                            <p th:if="${param.error}" th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message} " class="bg-danger"></p> <!-- 2 -->
                            <h2>使用账号密码登录</h2>
                            <form name="form" th:action="@{/login}" action="/login" method="POST"> <!-- 3 -->
                                <div class="form-group">
                                    <label for="username">账号</label>
                                    <input type="text" class="form-control" name="username" value="" placeholder="账号" />
                                </div>
                                <div class="form-group">
                                    <label for="password">密码</label>
                                    <input type="password" class="form-control" name="password" placeholder="密码" />
                                </div>
                                <input type="submit" id="login" value="Login" class="btn btn-primary" />
                            </form>
                        </div>
                    </div>

                </div>
            </div>

        </div>
    </div>
    <!--footer-->
    <div class="footer">
        <p>Copyright &copy; 2018.Company name All rights reserved.More Templates <a href="http://www.cssmoban.com/"
                                                                                    target="_blank"
                                                                                    title="模板之家">模板之家</a> - Collect from
            <a href="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></p></div>
    <!--//footer-->
</div>

<!-- side nav js -->
<script src='/static/js/SidebarNav.min.js' type='text/javascript'></script>
<script>
    $('.sidebar-menu').SidebarNav()
</script>
<!-- //side nav js -->

<!-- Classie --><!-- for toggle left push menu script -->
<script src="/static/js/classie.js"></script>
<script>
    var menuLeft = document.getElementById('cbp-spmenu-s1'),
        showLeftPush = document.getElementById('showLeftPush'),
        body = document.body;

    showLeftPush.onclick = function () {
        classie.toggle(this, 'active');
        classie.toggle(body, 'cbp-spmenu-push-toright');
        classie.toggle(menuLeft, 'cbp-spmenu-open');
        disableOther('showLeftPush');
    };

    function disableOther(button) {
        if (button !== 'showLeftPush') {
            classie.toggle(showLeftPush, 'disabled');
        }
    }
</script>
<!-- //Classie --><!-- //for toggle left push menu script -->

<!--scrolling js-->
<script src="/static/js/jquery.nicescroll.js"></script>
<script src="/static/js/scripts.js"></script>
<!--//scrolling js-->

<!-- Bootstrap Core JavaScript -->
<script src="/static/js/bootstrap.js"></script>
<!-- //Bootstrap Core JavaScript -->

</body>
</html>

3.application.properties(防止缓存)

spring.thymeleaf.cache=false

4.启动项目一直显示:

5.配置信息,备注刚开始进去是ASCII码。。。通过idea设置,显示为中文
setting->edit->File Encodings;

如下图:

6.核心部分来了,擦亮眼睛看。回到第4步,,为啥一直显示为红色区域?

参考网址:https://www.jianshu.com/p/b0cc88574f5d

我使用的第一个方案,实现的效果。。
很感谢上面网址的作者

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值