基于session的认证授权方式-SSM

基于session的认证授权方式-SSM

    具体流程:当用户登陆成功后,会在服务端将用户的相关信息保存到session中,而将发给客户端的session_id保存到cookie中,这样下次请求时带上session_id来校验服务端是否存在session数据,如果存在就校验通过,如果不存在就校验失败。当用户退出登录或session数据过期,就需要重新登录。

本案例工程使用maven进行构建,使用SpringMVC、Servlet3.0实现。

  • 导入spring-webmvc,javax.servlet-api依赖
    
    war
    
    
        UTF-8
        1.8
        1.8
    
    
    
        
            org.springframework
            spring-webmvc
            5.1.5.RELEASE
        
        
            javax.servlet
            javax.servlet-api
            3.0.1
            provided
        
    
    
        
            
                org.apache.tomcat.maven
                tomcat7-maven-plugin
                2.2
                
                    localhost        
                    8080                     
                    /   
                    UTF-8      
                
            
        
    
  • 定义spring容器配置类
//spring容器配置 相当于applicationContext.xml
@Configuration
//组件扫描springmvc包 排除controller包
@ComponentScan(basePackages = "com.gyf.security.springmvc"
            ,excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class)})
public class ApplicationConfig {
    //将配置文件中的配置拿到类中来配置
    //配置除了Controller的其他bean,如数据库连接池,事务管理器,业务bean等

}
  • 定义springmvc配置类
//servletContext配置  /相当于springvc.xml文件
//该类实现WebMvcConfigurer接口进行配置
//组件扫描springmvc包,包含Controller包
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.gyf.security.springmvc"
            ,includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class))
public class WebConfig implements WebMvcConfigurer {
    //视图解析器
    @Bean
    public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setPrefix("/WEB-INF/view/");
        internalResourceViewResolver.setSuffix(".jsp");
        return internalResourceViewResolver;
    }
    //添加视图控制器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
    }
    @Autowired
    private SimpleAuthenticationInterceptor simpleAuthenticationInterceptor;
    //添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //对指定的url进行拦截
        registry.addInterceptor(simpleAuthenticationInterceptor).addPathPatterns("/r/**");
    }
}
  • 手动加载spring配置文件
//手动加载spring配置类
//该类继承AbstractAnnotationConfigDispatcherServletInitializer,此类实现WebApplicationInitializer接口,Spring容器启动时加载WebApplicationInitializer接口的所有实现类
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    //加载spring容器 加载ApplicationContext.xml
    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class};
    }
    //servletContext 加载springmvc.xml
    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }
    //url-mapping
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
  • 自定义认证页面 lgoin.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>


    用户登录


用户名:
密   码:
  • 创建两个实体类 UserDto,AuthenticationRequest并添加get、set方法,构造方法
//用户表
public class AuthenticationRequest {
    //用户名
    private String username;
    //密码
    private String password;
}
//用户具体信息表
public class UserDto {
    public static final String SESSION_USER_KEY ="_user";
    //用户身份信息
    private String id;
    private String username;
    private String password;
    private String fullname;
    private String mobile;
    /**
     * 用户的权限
     */
    private Set authorities;
}
  • 业务层Service 自定义认证服务用于用户的身份认证
public interface AuthenticationService {
    //用户认证
    UserDto authentication(AuthenticationRequest request);
}
@Service
public class AuthenticationServiceImpl implements AuthenticationService {
    /**
     * 用户认证
     * @param request
     * @return
     */
    @Override
    public UserDto authentication(AuthenticationRequest request) {
        //校验参数是否为空
         if (request==null || StringUtils.isEmpty(request.getUsername()) || StringUtils.isEmpty(request.getPassword())){
             throw new RuntimeException("账号或密码为空");
         }
         //根据用户和密码去查询数据库 模拟数据库
        UserDto userDto = this.getUserDto(request.getUsername());
         //判断用户是否为空
        if (userDto==null){
            throw new RuntimeException("查询不到该用户");
        }
        //校验密码
        if (!request.getPassword().equals(userDto.getPassword())){
            throw new RuntimeException("密码错误");
        }
        //认证通过 返回用户的身份信息
        return userDto;
    }

    //用户信息 假装到数据库获取数据
    private Map map = new HashMap<>();
    //代码块
    {
        Set authorities1 = new HashSet<>();
        authorities1.add("p1");
        Set authorities2 = new HashSet<>();
        authorities2.add("p2");
        map.put("zhangsan",new UserDto("1010","zhangsan","123456","张三","123456",authorities1));
        map.put("lisi",new UserDto("1001","lisi","123","李四","789456",authorities2));
    }
    
    //根据账号查询用户信息
    private UserDto getUserDto(String username){
        UserDto userDto = map.get(username);
        return userDto;
    }
}
  • 表现层Controller 仅测试用
//@Controller+@ResponseBody
@RestController
public class LoginController {
    @Autowired
    private AuthenticationService authenticationService;

    //produces 存文本类型
    @RequestMapping(value = "/login",produces = "text/plain;charset=utf-8")
    public String login(AuthenticationRequest request, HttpSession httpSession){
        UserDto userDto = authenticationService.authentication(request);
        //将用户信息存入session
        httpSession.setAttribute(UserDto.SESSION_USER_KEY,userDto);
        return userDto.getUsername()+"登陆成功";
    }
    /**
     * 删除session中的数据
     * @param session
     * @return
     */
    @GetMapping(value = "/logout",produces = "text/plain;charset=utf-8")
    public String logout(HttpSession session){
        //删除session中的数据
        session.invalidate();
        return "退出成功";
    }
    /**
     * 判断session中是否有数据
     * @param session
     * @return
     */
    @GetMapping(value = "/r/r1",produces = "text/plain;charset=utf-8")
    public String r1(HttpSession session){
        String fullname = null;
        //到session中获取数据
        Object attribute = session.getAttribute(UserDto.SESSION_USER_KEY);
        if (attribute==null){
            fullname="匿名";
        }else {
            fullname=((UserDto)attribute).getFullname();
        }
        return fullname+"访问r1";
    }

    @GetMapping(value = "/r/r2",produces = "text/plain;charset=utf-8")
    public String r2(HttpSession session){
        String fullname = null;
        //到session中获取数据
        Object attribute = session.getAttribute(UserDto.SESSION_USER_KEY);
        if (attribute==null){
            fullname="匿名";
        }else {
            fullname=((UserDto)attribute).getFullname();
        }
        return fullname+"访问r2";
    }
}
  • 自定义拦截器 用于用户的授权
//spring中的组件
@Component
//实现 HandlerInterceptor接口
public class SimpleAuthenticationInterceptor implements HandlerInterceptor {
    //校验用户请求的url是否在用户的权限范围内
    //preHandle方法是在调用方法之前来调用这个方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 校验用户请求的url是否有权限访问
         */
        //获取session中的用户信息
        Object attribute = request.getSession().getAttribute(UserDto.SESSION_USER_KEY);
        //校验是否登录
        if (attribute==null){//代表session没有信息 提示登录
            writContext(response,"请登录");
            return false;
        }
        UserDto userDto = (UserDto) attribute;
        //获取请求url
        String requestURI = request.getRequestURI();
        if (userDto.getAuthorities().contains("p1")&&requestURI.contains("r/r1")){
            return true;
        }
        if (userDto.getAuthorities().contains("p2")&&requestURI.contains("r/r2")){
            return true;
        }
        writContext(response,"没有权限访问");
        return false;
    }

    //响应信息给前端
    private void writContext(HttpServletResponse response, String msg) throws IOException {
        //谁知响应格式
        response.setContentType("text/application;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //向前端返回数据
        writer.print(msg);
        writer.close();
    }
}

你可能感兴趣的:(基于session的认证授权方式-SSM)