SSM集成Shiro之使用注解在前后端分离项目中完成认证和授权

在之前的案例中使用Shiro完成授权的功能是通过Shiro的jstl表达式来对页面上的链接入口进行限制来完成的。
但是,在前后端分离的项目中,后端开发人员只负责开发后端接口,没有前台页面的支持。在此,我们可以使用Shirl的注解,来对Controller的Rest接口方法进行限定,通过不同的情况向页面返回不同的json数据。

一、创建ResultObj用于封装数据转换成json显示给前台

package com.xsh.pojo;

public class ResultObj {
    private String msssage;

    public ResultObj(String msssage) {
        this.msssage = msssage;
    }

    public String getMsssage() {
        return msssage;
    }

    public void setMsssage(String msssage) {
        this.msssage = msssage;
    }
}

二、解决用户未登录的访问问题

在之前,我们是在application-shiro.xml文件中配置了用户未登录时跳转到登录页面的相关配置。此时没有前端页面的支持,我们就需要创建Filter拦截未登录的请求并返回json提示。

package com.xsh.filter;

import com.alibaba.fastjson.JSON;
import com.xsh.pojo.ResultObj;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class ShiroLoginFilter extends FormAuthenticationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse rep= (HttpServletResponse) response;
        rep.setCharacterEncoding("UTF-8");
        rep.setContentType("application/json");
        ResultObj resultObj=new ResultObj("用户未登录");
        PrintWriter out = rep.getWriter();
        out.write(JSON.toJSONString(resultObj));
        out.flush();
        out.close();
        return false;
    }
}

以上过滤器继承了Shiro的FormAuthenticationFilter ,并且重写了onAccessDenied()方法,该方法会在未登录的请求访问的时候就被回调,所以可以通过这个方法的内容给前台显示未登录信息。

三、解决用户登录成功或者失败的显示问题

package com.xsh.controller;

import com.xsh.pojo.ResultObj;
import com.xsh.utils.ActivierUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/login")
public class LoginController {

    @RequestMapping("/login")
    public ResultObj login(String username, String password, HttpSession session){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);
        try{
            subject.login(token);
            ActivierUser activierUser = (ActivierUser) subject.getPrincipal();
            session.setAttribute("user",activierUser.getUser());
            return new ResultObj("登录成功");
        }catch (Exception e){
            return new ResultObj("登陆失败");
        }

    }
}

在此的解决方案非常简单,只是将返回的结果信息转换成了json数据。

四、完善相关控制器方法的权限限定

package com.xsh.controller;

import com.xsh.pojo.ResultObj;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    @RequiresPermissions(value = "user:query")
    @RequestMapping("/query")
    public ResultObj query(){
        return new ResultObj("用户查询");
    }
    @RequiresPermissions(value = "user:add")
    @RequestMapping("/add")
    public ResultObj add(){
        return new ResultObj("用户添加");
    }
    @RequiresPermissions(value = "user:update")
    @RequestMapping("/update")
    public ResultObj update(){
        return new ResultObj("用户修改");
    }
    @RequiresPermissions(value = "user:delete")
    @RequestMapping("/delete")
    public ResultObj delete(){
        return new ResultObj("用户删除");
    }


}

在该控制器中,通过@RequiresPermissions注解来对控制器方法进行了权限限定。
但是此时并不能生效,已知Shiro的验证是通过异常来进行结果的显示,也就是说当用户访问权限不够的时候Shiro会返回一个UnauthorizedException异常。
所以,在此我们需要开启Shiro的注解支持,并且拦截UnauthorizedException异常来返回提示信息

五、在springmvc.xml文件中添加Shiro的注解支持

 <!--开启Shiro的注解支持-->
    <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" id="lifecycleBeanPostProcessor"></bean>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"></bean>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"></property>
     </bean>

六、创建拦截全局异常监听类监听UnauthorizedException异常

package com.xsh.handler;

import com.xsh.pojo.ResultObj;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常监控,当项目中发生异常就会触发其中的方法
 */
@RestControllerAdvice
public class GlobalExceptionHanderAdvise {
    /**
     * 监听Shiro的未授权异常,当用户访问权限不够的功能时就会触发该异常
     * 该方法监听这个异常然后返回json提示信息
     * @return
     */
    @ExceptionHandler(value = {UnauthorizedException.class})
    public ResultObj Unauthorized(){
        return new ResultObj("权限不够");
    }

}

此时,使用注解来完成用户权限验证就结束了。如果在springmvc.xml文件中扫描注解的包范围太小就必须要添加全局异常监听类的注解扫描,不然该类也无法发挥作用。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSMSpring+SpringMVC+MyBatis)是一种常用的Java后端开发框架,而Vue是一种流行的前端开发框架。将它们结合起来进行前后端分离开发可以提高开发效率和代码的可维护性。 在SSM Vue前后端分离项目,后端使用SSM框架进行开发,前端使用Vue框架进行开发。前后端通过API接口进行数据交互。 下面是一个简单的SSM Vue前后端分离项目的示例: 1. 后端开发: - 使用Spring框架进行依赖注入和事务管理。 - 使用SpringMVC框架处理HTTP请求和响应。 - 使用MyBatis框架进行数据库操作。 - 设计并实现RESTful API接口,提供数据的增删改查功能。 2. 前端开发: - 使用Vue框架进行组件化开发。 - 使用Vue Router进行路由管理,实现页面跳转和导航。 - 使用Vuex进行状态管理,实现数据共享和响应式更新。 - 使用Axios库发送HTTP请求,与后端API进行数据交互。 - 使用Element UI或其他UI库进行页面布局和样式设计。 3. 前后端交互: - 前端通过Axios库发送HTTP请求到后端API接口,获取数据或提交数据。 - 后端接收请求,处理业务逻辑,访问数据库进行数据操作。 - 后端将处理结果返回给前端,前端根据结果进行相应的展示或处理。 这样的前后端分离项目可以提高开发效率和团队协作能力,前后端可以独立开发和测试,减少了耦合性,同时也方便进行项目的扩展和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值