8.基于Session的认证方式-实现授权功能

实现授权功能

  • 现在我们已经完成了用户身份凭证的校验以及登录的状态保持,并且我们也知道了如何获取当前登录用户(从Session中获取)的信息,接下来,用户访问系统需要经过授权,即需要完成如下功能:
  • 匿名用户(未登录用户)访问拦截:禁止匿名用户访问某些资源。
  • 登录用户访问拦截:根据用户的权限决定是否能访问某些资源。
  • (1)增加权限数据
  • 为了实现这样的功能,我们需要在UserDto里增加权限属性,用于表示该登录用户所拥有的权限,同时修改UserDto的构造方法。
/**
 * 用户身份信息
 */
@Data
@AllArgsConstructor
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<String> authorities;
}
  • 并在AuthenticationServletImpl中为模拟用户初始化权限,其中张三给了p1权限,李四给了p2权限。
/**
 * 用户信息
 */
private Map<String,UserDto> userDtoMap=new HashMap<>();
{
    Set<String> authorities1=new HashSet<>();
    authorities1.add("p1");//这个p1我们认为让它和/r/r1对应
    Set<String> authorities2=new HashSet<>();
    authorities2.add("p2");//这个p1我们认为让它和/r/r2对应

    userDtoMap.put("zs",new UserDto("1010","zs","123","张三","1224443",authorities1));
    userDtoMap.put("ls",new UserDto("1011","ls","123","李四","1224443",authorities2));
}
  • (2)添加测试资源
  • 我们想实现针对不同用户能访问不同的资源,前提是得有多个资源,因此在LoginController中增加测试资源2。
@RequestMapping(value = "/r/r2", produces = "text/plain;charset=utf-8")
public String r2(HttpSession session) {
    String fullname = null;
    Object object = session.getAttribute(UserDto.SESSION_USER_KEY);
    if (object == null) {
        fullname = "匿名";
    } else {
        UserDto userDto = (UserDto) object;
        fullname = userDto.getFullname();
    }
    return fullname + "访问资源r2";
}
  • (实现授权拦截器)
  • 在interceptor包下定义SimpleAuthenticationInterceptor拦截器,实现授权拦截:
  • 1.校验用户是否登录
  • 2.校验用户是否拥有操作权限
@Component
public class SimpleAuthenticationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //在这个方法中校验用户请求得url是否在用户得权限范围内
        //取出用户得身份信息
        Object object = request.getSession().getAttribute(UserDto.SESSION_USER_KEY);
        if (object==null){
            //没有认证,提示登录
            writeContent(response,"请登录");
        }
        UserDto userDto= (UserDto) object;
        //请求的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;
        }
        writeContent(response,"没有权限,拒绝访问");
        return false;
    }

    /**
     * 响应信息给客户端
     * @param response
     * @param msg
     */
    private void writeContent(HttpServletResponse response, String msg) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println(msg);
        writer.close();
        response.resetBuffer();
    }
}
  • 在WebConfig中配置拦截器,匹配/r/**的资源为受保护的系统资源,访问资源的请求进入SimpleAuthenticationInterceptor拦截器。
@Autowired
SimpleAuthenticationInterceptor simpleAuthenticationInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(simpleAuthenticationInterceptor);
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容