实现安全登录的两种方法

实现安全登录的两种方法登录安全——拦截器和过滤器或权限框架的使用本次我们将采用两种方法实现登录的安全性,首先介绍拦截器和过滤器。一、 过滤器和拦截器:过滤器产生的时间/开始工作的时间:进入Tomcat之后,但是在进servlet之前。Interceptor进入了servlet所以拦截器拦截的是动作,而过滤器拦截的是不合理的跳转页面。1、配置和使用拦截器。<mvc:interceptors>&…

大家好,又见面了,我是你们的朋友全栈君。

登录安全——拦截器和过滤器或权限框架的使用

本次我们将采用两种方法实现登录的安全性,首先介绍拦截器和过滤器。
一、 过滤器和拦截器:
过滤器产生的时间/开始工作的时间: 进入Tomcat之后,但是在进servlet之前。Interceptor进入了servlet
所以拦截器拦截的是动作,而过滤器拦截的是不合理的跳转页面。

1、配置和使用拦截器。

<mvc:interceptors>
<mvc:interceptor>
    <!--   1.拦截所有的请求      -->
    <mvc:mapping path="/**"/>
    <!--  2.  mvc:exclude-mapping : 是一种拦截,可以放行或者对某个请求不拦截,     -->
    <mvc:exclude-mapping path="/user/doLogin.do"/>
    <!--  3. 告诉我们要用哪个拦截器      -->
    <bean class="com.zhongruan.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>

</mvc:interceptors>

解释:除了login之外的请求都不允许执行

public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //在拦截点执行前拦截,如果返回true,则不执行拦截点后的才做
    //获取session
    HttpSession session = request.getSession();
    //获取访问路径
    String uri = request.getRequestURI();
    //indexOf函数:求出字符串内路径出现的下标
    if(session.getAttribute("userInfo")!=null){
        //登录成功,不拦截
        return true;
    }else{
        //拦截成功
        response.sendRedirect(request.getContextPath()+"user/doLogin.do");
        return false;
    }

}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    //处理过程中,执行拦截
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    //执行完毕之后,返回前拦截
}

}

重写拦截点前拦截动作的函数:
如果登录成功,则证明是真正的用户,所以放弃拦截(拦截器也因此失效);如果登录失败,则重新返回登录界面,且无法输入其他动作跳转到其他界面。

2、配置和使用过滤器:

<filter>
 <filter-name>SessionFilter</filter-name>
 <filter-class>com.zhongruan.filter.LoginFilter</filter-class>
 </filter>

 <filter-mapping>
 <filter-name>SessionFilter</filter-name>
 <url-pattern>/pages/*</url-pattern>
 <url-pattern>*.jsp</url-pattern>
 </filter-mapping>

上面是指请求所有界面都要通过过滤器,filter的实现如下:

   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    //区别:Interceptor进入了servlet,所以重写的参数时HttpServletRequest/Response
    //   Filter没有进入Servlet.ServletRequest
    //  ServletRequest是接口,HttpServletRequest是实现,这里有些方法是HttpServletRequest中独有的,例如getSession
    //所以要强制转换
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse)servletResponse;
    //以下类似拦截器了
    HttpSession session = request.getSession();
    if(session.getAttribute("userInfo") == null && request.getRequestURI().indexOf("/user/doLogin.do") == -1){
        // 没有登录,返回登录页面
        response.sendRedirect(request.getContextPath()+"/user/doLogin.do");
    }else{
        //已经登录了,继续请求下一步操作
        filterChain.doFilter(request,response);
    }
}

同样,过滤器使用过后就会失效,如果是真正的用户,可以访问其他界面,否则不能在登录界面访问其他界面。

结果展示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
二、 使用权限框架Spring-Security
1、首先在pom.xml文件中导入框架需要的jar包

<!--  spring.security架包      -->
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>${spring.security.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>${spring.security.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-core</artifactId>
  <version>${spring.security.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-taglibs</artifactId>
  <version>${spring.security.version}</version>
</dependency>

2、配置web.xml文件
添加如下语句:

<!--   配置 Spring-security;添加过滤器拦截所有请求  -->
 <filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>
 <filter-mapping>
   <filter-name>springSecurityFilterChain</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

3、添加角色类:
由于验证机制是可以将用户类和管理员类区分开,登录后进入不同的界面,所以我们要增加一个角色类Role,它有三个属性:id,roleName和roleDesc,还有它们的get/set方法以及toString方法。
另外在UserInfo类中添加新的属性roleList(一个人可能对应多个角色)及其对应的方法。

4、添加Dao层:
新建一个名为“RoleDao”的接口类,并定义一个List findRoleByUserId(int userId);
方法。

 <select id="findRoleByUserId" parameterType="java.lang.Integer"        resultType="com.zhongruan.bean.Role">
    select * from tb_Role where id in(select roleId from tb_user_role    where userId=#{userId})
 </select>

可以看出,这个sql语句使用了多表查询。先在tb_user_role表中根据userid查询该用户的roleid,再在tb_Role表中查找该roleid对应的角色是什么。

5、service层:

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    // 1. 查询当前登录的用户信息
    UserInfo userInfo = userDao.doLogin(username);
    System.out.println("获得的用户线信息为:"+ userInfo);
    // 2. 查询当前的用户有多少角色
    List<Role> roleList = roleDao.findRoleByUserId(userInfo.getId());
    // 3. 需要把角色给放入用户中
    userInfo.setRoleList(roleList);

    // 4. 把查询到的User和Role数据  给到Spring-security中的内置对象User来管理
    User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), getAuthority(userInfo.getRoleList()));
    return user;

}
下面是getAuthority的代码:

private Collection<? extends GrantedAuthority> getAuthority(List<Role> roleList) {
List<SimpleGrantedAuthority> list = new ArrayList<>();
for(Role role:roleList){
    list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
}
return list;

}
6、准备spring-security文件:

    <security:global-method-security pre-post-annotations="enabled" jsr250-annotations="enabled" secured-annotations="enabled"></security:global-method-security>

<!-- 配置不拦截的资源 -->
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>
<!--
   配置具体的规则
   auto-config="true" 不用自己编写登录的页面,框架提供默认登录页面
   use-expressions="false"    是否使用SPEL表达式(没学习过)
-->
<security:http auto-config="true" use-expressions="true">
    <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
    <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>

    <security:form-login login-page="/login.jsp"
                         login-processing-url="/login.do"
                        default-target-url="/index.jsp"
                        authentication-failure-url="/failer.jsp"
                        authentication-success-forward-url="/pages/main.jsp"/>

    <!-- 关闭跨域请求 -->
    <security:csrf disabled="true"/>

    <!--退出并跳转到首页-->
    <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp"></security:logout>
</security:http>

<!-- 切换成数据库中的用户名和密码 -->
<security:authentication-manager>
    <security:authentication-provider user-service-ref="userService">
        <!-- 配置加密的方式
        <security:password-encoder ref="passwordEncoder"/> -->
    </security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密类 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

7、login.jsp页面:

这里直接用login.do而不是doLogin.do(之前的函数已经被注释掉了)。这个login.do的实现是在框架里写所以我们不需要管。

Aside.jsp页面:
由于登录后会在左上角显示登录用户的头像和信息以及可以进行的操作,所以需要在下拉菜单的链接加上一句<security:authentication property=“principal.username”></security:authentication>
同时加上如下代码:

<security:authorize access="hasRole('ADMIN')">
 <a
 href="${pageContext.request.contextPath}/user/findAll.do?page=1&size=5"> <i
  class="fa fa-circle-o"></i> 用户管理
</a>
 </security:authorize>

意思是只有管理员拥有“用户管理”这个选项,普通用户界面不显示。
下面是运行结果展示:

如果是输入了错误的用户名或密码:
在这里插入图片描述

如果是管理员身份成功登录:
在这里插入图片描述
如果是用户身份成功登录:
在这里插入图片描述
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125017.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月19日 下午6:00
下一篇 2022年4月19日 下午6:00


相关推荐

  • 深度linux iso镜像,深度 Deepin 15 正式版 ISO 镜像下载 – 精美易用适合国人学习的国产 Linux 发行版……「建议收藏」

    深度linux iso镜像,深度 Deepin 15 正式版 ISO 镜像下载 – 精美易用适合国人学习的国产 Linux 发行版……「建议收藏」本帖最后由javy于2016-1-822:06编辑现在除了Windows和Mac之外,越来越多朋友想要学习使用一下Linux系统。不过,国外的诸如CentOS、Ubuntu似乎“专业”了一点,对于新手/普通用户,面向国人的优麒麟或深度操作系统可能更加合适。作为优秀的国产Linux发行版之一,深度Deepin操作系统近年来发展相当迅速,团队投入了十足精力开发和精心设计…

    2022年5月16日
    56
  • 滑动窗口 leetcode_滑动窗口的概念

    滑动窗口 leetcode_滑动窗口的概念原题链接给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。示例 1:输入:nums = [1,3,-1,-3,5,3,6,7], k = 3输出:[3,3,5,5,6,7]解释:滑动窗口的位置 最大值————— —–[1 3 -1] -3 5 3 6 7

    2022年8月8日
    7
  • org.apache.jasper.JasperException: /WEB-INF/view/../../../common/common1.jsp (line: 7, column: 1) Pa…

    org.apache.jasper.JasperException: /WEB-INF/view/../../../common/common1.jsp (line: 7, column: 1) Pa…

    2022年3月12日
    47
  • 模糊控制器matlab仿真_有关bp神经网络Matlab的书

    模糊控制器matlab仿真_有关bp神经网络Matlab的书以下多套系统源码:1、MATLAB二级倒立摆三级倒立摆(在MATLAB下的二级倒立摆、三级倒立摆的仿真。内有所有需要的m文件)2、倒立摆matlab代码3、神经网络倒立摆控制(利用matlab对倒立摆的仿真,效果十分不错)4、二级倒立摆模型(这是一个演示直线二级倒立摆的matlab运行模型,这个模型能够根据仿真数据动画演示出二级倒立摆的运动情况。)5、倒立摆源码(倒立摆源码程序,注释很详细,是学习倒立摆原理,PID算法很好的参考资料。代码书写规范,注释详细。)6、二级倒立摆神经网络控制7

    2022年8月18日
    11
  • ps测量精灵图[通俗易懂]

    ps测量精灵图[通俗易懂]1.调出图片信息2.测量图片大小、3.把鼠标放在需要用到的小图片的左上角  精灵图的测量:B站中有详细的教程    第43集  京东项目精灵图的使用:B站精灵图的使用第24集   李江南讲解精灵图第44集  定位口诀:子绝父相(孩子是绝对定位,父亲是相对定位;)…

    2022年6月10日
    39
  • 讲座:计算机专业及其学习

    讲座:计算机专业及其学习

    2022年1月21日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号