10-9-用户登录控制
一、请求处理层实现
创建一个用户登录管理的控制类文件LoginController,并编写向自定义登录页面跳转的请求控制方法
@Controller
public class LoginController {
// 向登录页面跳转,同时封装原始页面地址
@GetMapping(value = "/login")
public String login(HttpServletRequest request, Map map) {
// 分别获取请求头和参数url中的原始访问路径
String referer = request.getHeader("Referer");
String url = request.getParameter("url");
System.out.println("referer= "+referer);
System.out.println("url= "+url);
// 如果参数url中已经封装了原始页面路径,直接返回该路径
if (url!=null && !url.equals("")){
map.put("url",url);
// 如果请求头本身包含登录,将重定向url设为空,让后台通过用户角色进行选择跳转
}else if (referer!=null && referer.contains("/login")){
map.put("url", "");
}else {
// 否则的话,就记住请求头中的原始访问路径
map.put("url", referer);
}
return "comm/login";
}
// 对Security拦截的无权限访问异常处理路径映射
@GetMapping(value = "/errorPage/{page}/{code}")
public String AccessExecptionHandler(@PathVariable("page") String page, @PathVariable("code") String code) {
return page+"/"+code;
}
}
二、实现前端页面功能
comm文件夹下的自定义用户登录页面login.html进行自定义用户登录功能查看和实现
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>登录博客后台</title>
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<link rel="shortcut icon" th:href="@{/user/img/bloglogo.jpg}"/>
<script th:src="@{/assets/js/jquery.min.js}"></script>
<script th:src="@{/assets/js/amazeui.min.js}"></script>
<link rel="stylesheet" th:href="@{/assets/css/amazeui.min.css}"/>
<link rel="stylesheet" th:href="@{/assets/css/app.css}"/>
</head>
<body>
<div class="log">
<div class="am-g">
<div class="am-u-lg-3 am-u-md-6 am-u-sm-8 am-u-sm-centered log-content">
<h1 class="log-title am-animation-slide-top" style="color: black;" th:text="#{login.welcomeTitle}">~欢迎登录博客~</h1>
<br>
<div th:if="${param.error}" style="color: red" th:text="#{login.error}">用户名或密码错误!</div>
<form class="am-form" id="loginForm" th:action="@{/login}" method="post">
<div>
<input type="hidden" name="url" th:value="${url}">
</div>
<div class="am-input-group am-radius am-animation-slide-left">
<input type="text" class="am-radius" th:placeholder="#{login.username}" name="username" />
<span class="am-input-group-label log-icon am-radius">
<i class="am-icon-user am-icon-sm am-icon-fw"></i>
</span>
</div>
<br>
<div class="am-input-group am-animation-slide-left log-animation-delay">
<input type="password" class="am-form-field am-radius log-input" th:placeholder="#{login.password}" name="password" />
<span class="am-input-group-label log-icon am-radius">
<i class="am-icon-lock am-icon-sm am-icon-fw"></i>
</span>
</div>
<div style="padding-top: 10px;">
<input type="submit" th:value="#{login.sub}"
class="am-btn am-btn-primary am-btn-block am-btn-lg am-radius am-animation-slide-bottom log-animation-delay" />
</div>
</form>
</div>
</div>
<footer class="log-footer">
<p style="margin: 30px; color: #2E2D3C"><time class="comment-time" th:text="${#dates.format(new java.util.Date().getTime(), 'yyyy')}"></time> © Powered By <a style="color: #0e90d2" rel="nofollow">CrazyStone</a></p>
</footer>
</div>
</body>
</html>
注:
核心内容是编写了一个用户登录的<form>表单,并使用Thymeleaf模板的“#{}”表达式进行了登录表单信息的国际化设置。
该用户登录功能也是使用了<form>表单进行POST方式提交请求的,由于使用了Thymeleaf的th:action="@{/login}"属性进行请求处理,所以无需手动添加用于CSRF防御时进行CSRF Token认证的隐藏域。
三、编写Security认证授权配置类
创建一个用于整合Security进行安全控制的配置类SecurityConfig,并重写自定义用户认证和授权方法,使用JDBC身份认证的方式实现了自定义用户认证,此时重启项目进行访问,则只需要输入数据库中已有的用户信息就可以登录认证。
@EnableWebSecurity // 开启MVC security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
/**
* 重写configure(AuthenticationManagerBuilder auth)方法,进行自定义用户认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 密码需要设置编码器
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// 使用JDBC进行身份认证
String userSQL ="select username,password,valid from t_user where username = ?";
String authoritySQL ="select u.username,a.authority from t_user u,t_authority a," +
"t_user_authority ua where ua.user_id=u.id " +
"and ua.authority_id=a.id and u.username =?";
auth.jdbcAuthentication().passwordEncoder(encoder)
.dataSource(dataSource)
.usersByUsernameQuery(userSQL)
.authoritiesByUsernameQuery(authoritySQL);
}
}
继续在SecurityConfig配置类中编写自定义用户授权管理的实现,自定义用户授权管理方法中主要配置了自定义的用户访问控制、用户登录控制、用户登录后的Cookie设置、用户退出控制和登录用户无权限访问控制。
@Value("${COOKIE.VALIDITY}")
private Integer COOKIE_VALIDITY;
/**
* 重写configure(HttpSecurity http)方法,进行用户授权管理
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 1、自定义用户访问控制
http.authorizeRequests()
.antMatchers("/","/page/**","/article/**","/login").permitAll()
.antMatchers("/back/**","/assets/**","/user/**","/article_img/**").permitAll()
.antMatchers("/admin/**").hasRole("admin")
.anyRequest().authenticated();
// 2、自定义用户登录控制
http.formLogin()
.loginPage("/login")
.usernameParameter("username").passwordParameter("password")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
String url = httpServletRequest.getParameter("url");
// 获取被拦截的原始访问路径
RequestCache requestCache = new HttpSessionRequestCache();
SavedRequest savedRequest = requestCache.getRequest(httpServletRequest,httpServletResponse);
if(savedRequest !=null){
// 如果存在原始拦截路径,登录成功后重定向到原始访问路径
httpServletResponse.sendRedirect(savedRequest.getRedirectUrl());
} else if(url != null && !url.equals("")){
// 跳转到之前所在页面
URL fullURL = new URL(url);
httpServletResponse.sendRedirect(fullURL.getPath());
}else {
// 直接登录的用户,根据用户角色分别重定向到后台首页和前台首页
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
boolean isAdmin = authorities.contains(new SimpleGrantedAuthority("ROLE_admin"));
if(isAdmin){
httpServletResponse.sendRedirect("/admin");
}else {
httpServletResponse.sendRedirect("/");
}
}
}
})
// 用户登录失败处理
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
// 登录失败后,取出原始页面url并追加在重定向路径上
String url = httpServletRequest.getParameter("url");
httpServletResponse.sendRedirect("/login?error&url="+url);
}
});
// 3、设置用户登录后cookie有效期,默认值
http.rememberMe().alwaysRemember(true).tokenValiditySeconds(COOKIE_VALIDITY);
// 4、自定义用户退出控制
http.logout().logoutUrl("/logout").logoutSuccessUrl("/");
// 5、针对访问无权限页面出现的403页面进行定制处理
http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
// 如果是权限访问异常,则进行拦截到指定错误页面
RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher("/errorPage/comm/error_403");
dispatcher.forward(httpServletRequest, httpServletResponse);
}
});
}
四、效果展示
启动项目进行测试,访问项目前端首页,无需登录,如图。
10-9-用户登录控制相关推荐
- SSH远程管理(用户登录控制及密码验证)
SSH (secure shell) 是一种安全通道协议,主要实现字符界面的远程登录,远程复制等功能.SSH协议对通信双方的数据进行了加密处理, 其中包括用户登录时输入的用户口令. 实验环境:两台L ...
- Ubuntu12.10 root用户登录设置
ubuntu12.10默认不允许root用户登录,在登录窗口只能看到普通用户和访客登录. 以普通身份登陆ubuntu后,我们需要做一些修改 普通用户登录后,修改系统配置文件需要切换到超级用户模式,在终 ...
- 系统安全及应用(账户安全控制,系统引导和登录,弱口令检测和登录控制,PAM认证,端口扫描,用户切换和提权)
文章目录 系统安全及应用 账户安全控制 基本安全措施 chattr--锁定账号配置文件 密码安全控制( chage) 要求用户下次登录时修改密码 命令历史,自动注销 注销时自动清空命令历史: bash ...
- ORACLE 触发器控制用户登录之权限限制
出于数据安全性,公司要求DBA实现控制拒绝特定的用户登录,由于公司不同的工作楼层分属于不同的vlan,因此单从linux主机层次依赖ACL访问列表控制登录数据库服务器,已经不能实现. 因此,只能考虑从 ...
- WEB综合案例 黑马面面 day04 用户与角色绑定功能 登录用户菜单控制和权限效验
WEB综合案例 day04 用户与角色绑定功能 登录用户菜单控制和权限效验 1. 用户与角色 思路: 根据用户去找角色的信息,然后需要用到两个表的查询,在前端页面显示信息的时候用for:each通过遍 ...
- mysql用户控制登录_MySql用户权限控制_MySQL
bitsCN.com MySql用户权限控制 本文将介绍MySql创建帐号,删除帐号,设置和介绍各种帐号的权限 创建用户帐号: www.bitsCN.com [sql] CREATE USER use ...
- 软件评测-信息安全-应用安全-资源控制-用户登录限制(中)
最近需要把通用权限管理系统送到软件评测中心进行信息安全测试,其中有就有一项检查内容叫:"资源控制-用户登录限制",为了达到这个检查项目的要求,我们程序也进行了改进,同时也是为了达到 ...
- shiro实现url级别的权限控制(用户登录)配置文件分析
shiro实现url级别的权限控制(用户登录)
- 软件评测-信息安全-应用安全-资源控制-用户登录限制(上)
最近需要把通用权限管理系统送到软件评测中心进行信息安全测试,其中有就有一项检查内容叫:"资源控制-用户登录限制",为了达到这个检查项目的要求,我们程序也进行了改进,同时也是为了达到 ...
最新文章
- 基于单片机的水壶自动加热系统_基于单片机的智能热水壶设计说明
- 今天做内存操作系统(xp装在内存中)
- win7下一次加载和调试sys驱动程序的过程以及捕捉到内核打印字符串函数的输出
- java编程_Java编程和C语言的比较
- MYSQL授权root远程访问
- 怎样登陆微信小程序?怎样登陆微信小程序后台?微信小程序成员如何登陆后台管理?微信小程序怎么登录,如何正确登录微信小程序后台?微信小程序如何登录页面?具体操作步骤如下
- Android Studio 解决数据库手机电脑不同步
- 点击图标分享页面到QQ,微信,微博 等
- python爬虫+数据分析完整流程--豆瓣电影分类排行榜
- otter实现数据同步,otter manger的安装
- OIer专用-网址导航
- 华为手机灵敏度设置_华为调屏幕灵敏度设置方法
- 5941. 找出知晓秘密的所有专家
- 采取HEXO+NexT主题+github.io的方式建立自己的个人主页
- 盘一盘 Python 系列 - Cufflinks (下)
- F005-如是我观,知识产权 #F520
- 昨天介入600571,信雅达,喜欢的朋友可以跟进!
- C++ throw()关键词:一个被C++标准抛弃的玩意儿
- 基于Python机器学习对某地区房地产数据分析预测报告
- ArrayMap的源码分析
热门文章
- Day7--误差反向传播
- 【Flink】Flink SQL Cannot instantiate user function cannot assign instance LinkedMap FlinkKafkaConsum
- 【Elasticsearch】es 7.12 Root mapping definition has unsupported parameters: _all
- Spark类型不匹配导致无法读取到数据
- Spark连接hive
- Docker : Error response from daemon: Get https://docker.elastic.co/v2/: net/http: TLS handshake time
- 【Docker】Mac下Docker启动Kubernetes
- 95-290-340-源码-内存管理-Buffer-ByteBuffer简介
- 【安全】Apache HDFS 上配置 kerberos
- ecs服务器换系统,ecs服务器更换操作系统