实习DAY6


2019年7月17日

在项目中加入拦截器与过滤器

拦截器

拦截的是 action,说白了拦截的是访问路径。
配置拦截器:interceptor
spring-mvc.xml

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

        </mvc:interceptor>
    </mvc:interceptors>

创建目录与java文件"com.zhongruan.interceptor.LoginInterceptor",实现拦截器。
LoginInterceptor.java:

package com.zhongruan.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


//定义拦截器类
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 || uri.indexOf("/user/doLogin.do") != -1){
            //登陆成功,不拦截
            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 {
        //执行完毕之后,返回前拦截
    }
}

过滤器

可以几乎过滤掉所有的东西。
web.xml:

   <!--配置过滤器-->
  <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>

创建目录与java文件"com.zhongruan.filter.LoginFilter",实现过滤器。
LoginFilter.java:

package com.zhongruan.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //过滤器出生
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //区别:Interceptor进入了servlet,所以重写的参数是HttpServletRequest/Response
        //      filter没有进入Servlet,ServletRequest
        // ServletRequest是接口,HttpServletRequest是实现,这里有些方法是HttpServletRequest中独有的,例如getSession
        //1.强制转换
        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);
        }
    }

    @Override
    public void destroy() {

    }
}

实现权限框架,Spring-Security的使用

理解: 是spring项目组中 提供 安全认证服务的框架
认证:验证用户密码是否正确的过程
授权:对用户所能访问的资源进行控制

数据库

先建表:tb_user_role是用来匹配用户id和该用户应该有的角色的id,比如admin有两种角色,分别是admin和user,则表数据应该如下:
在这里插入图片描述
tb_user
tb_user_role
在这里插入图片描述
tb_role

服务端目录结构更新

bean的UserInfo的属性要新增一项:
在这里插入图片描述
bean的新实体类Role:注意这里的实体类是没有构造函数(应该是由spring-security插件实现的),所以如有bug可以从这里入手解决。

package com.zhongruan.bean;
/*
* 角色的实体
* */
public class Role {
   private int id;
   private String roleName;
   private String roleDesc;

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }
}

RoleDao:

package com.zhongruan.dao;

import com.zhongruan.bean.Role;

import java.util.List;

public interface RoleDao {

    //在tb_user_role中,根据userID查询出当前的用户
    List<Role> findRoleByUserId(int userId);

}

导架包 – Pom.xml

第一行放到properties中,dependency就放到denpendencies中。

        <spring.security.version>5.0.1.RELEASE</spring.security.version>
		
		
		<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>

在这里插入图片描述

配置web.xml

注意该标签要放在当前文件的<beans>中。

<!--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>

新建 Spring-Security.xml

目录结构:
在这里插入图片描述

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<security:global-method-security pre-post-annotations="enabled" jsr250-annotations="enabled" secured-annotations="enabled"/>
 <!--  配置不拦截的资源  -->
<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: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"/>
 <!--
 <bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
-->
 <!--
 提供了入门的方式,在内存中存入用户名和密码
    <security:authentication-manager>
    	<security:authentication-provider>
    		<security:user-service>
    			<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
    		</security:user-service>
    	</security:authentication-provider>
    </security:authentication-manager>
    
-->
</beans>

配置文件中的userService是在这里响应的:
userServiceImpl.java:
在这里插入图片描述

Web.xml里,加载配置文件

注意这里的配置:
在这里插入图片描述

UserService继承 UserDeatilsService

在这里插入图片描述
在UserSeriviceImpl中右键generator并选择Override Method
在这里插入图片描述
在这里插入图片描述
重写这个方法:

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //1.查询当前登陆的用户信息
        UserInfo userInfo = userDao.doLogin(username);
        //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;
    }

    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;
    }

另外:
aside.jsp实现不同角色的用户显示不同的界面(同一界面,标签的不同来实现)。

<%@taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

在这里插入图片描述
用户名显示:
在这里插入图片描述
不同角色不同界面:
在这里插入图片描述
login.jsp:引入了新的插件所以也需要修改登陆时设置的请求名字:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值