Shiro学习(二)-Web环境下使用Shiro进行身份认证

web环境下使用shiro

在SSM中集成shiro,使用shiro完成系统登录功能,相当于完成系统中的登录功能以及登录检查拦截器的功能。如果有对基本原理不太明白,请去翻看上一篇博客。

  1. 在web.xml添加shiro过滤器代理的配置,该代理会从spring容器中找到shiroFilter并执行
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  1. 抽取shiro.xml专门配置shiro相关,在mvc中引入此配置即可
    主要配置什么:配置shiroFilter,配置securityManager安全管理器,配置我们自定义的realm(我们自定义的类可以使用@Component取代xml配置),为shiroFilter注入securityManager,为securityManager注入realm。此外,在shiroFilter中我们需要为不同类型的请求资源去定义合适的过滤器
  • 常用过滤器
    a. anon:org.apache.shiro.web.filter.authc.AnonymousFilter,匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤
    b. authc:org.apache.shiro.web.filter.authc.FormAuthenticationFilter,表示需要认证(登录)才能使用
    c. roles:org.apache.shiro.web.filter.authz.RolesAuthorizationFilter,角色授权拦截器,验证用户是否拥有资源角色;
    d. perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter,权限授权拦截器,验证用户是否拥有资源权限
    e. logout:org.apache.shiro.web.filter.authc.LogoutFilter,访问/logout.do进行登陆注销

补充shiroFilter中的其他属性配置:usernameParam:表单提交的用户名参数名( username); passwordParam:表单提交的密码参数名(password); rememberMeParam:表单提交的密码参数名(rememberMe); loginUrl:登录页面地
注意前端页面表单参数必须为username和password,如果不是,请按照补充的内容做出相应修改

完整配置

    <!--Ioc-->
    <context:component-scan base-package="cn.wolfcode.crm.shiro"/>
    <!--shiro相关配置-->
    <!--配置shiro过滤器,注意此bean的名称必须和web.xml中filter-name保持一致-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!--配置登陆页面-->
        <property name="loginUrl" value="/login.html"></property>
        <!--配置过滤规则-->
        <property name="filterChainDefinitions">
            <value>
                <!--静态资源不需要验证-->
                /js/**=anon
                /images/**=anon
                /css/**=anon
                /bootstrap/**=anon
                /jquery/**=anon
                <!--访问/logout.do进行登陆注销-->
                /logout.do=logout
                <!--其余资源都需要认证(登录)-->
                /**=authc
            </value>
        </property>
        <!--注意上述对authc的过滤是FormAuthenticationFilter在做,观察代码可知
            登陆成功(onLoginSuccess)他只会返回true,失败返回false
            但是我们表单是用ajax的post方式提交,会接收json数据,但是默认的FormAuthenticationFilter无法满足
            此处我们自定义filter实现我们想要的功能,继承与FormAuthenticationFilter
        -->
        <property name="filters">
            <map>
                <entry key="authc" value-ref="authcFilter"></entry>
            </map>
        </property>
    </bean>
    <!--配置安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
    </bean>
  1. 我们自定义MyRealm,主要功能是根据传来的token调用service方法到数据库查处安全数据源,然后到封装认证信息并返回
@Component("myRealm")
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private IEmployeeService employeeService;

    //权限认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //从数据库中获取安全数据
       Employee emp = employeeService.getEmployeeByUsername(token.getPrincipal());
        System.out.println("emp:"+emp);
       if(emp == null){
           return  null;
       }
       return new SimpleAuthenticationInfo(emp.getName(),emp.getPassword(),getName());
    }
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}
  1. 我们自定义MyAuthcFilter继承于FormAuthenticationFilter,为什么自定义?针对于realm返回的info,如果没有任何异常,会进入FormAuthenticationFilter的onSuccessLogin()方法,会返回true;返回info为null,进入onLoginFailed()方法返回false;但是,我们前端页面使用ajax提交表单,需要接受json返回数据,所以FormAuthenticationFilter不满足需要,我们自定义Filter继承于它,可以覆盖上面两个方法,返回成功或失败的json数据

JsonResult:简单封装返回的json数据,success标志有没有成功,message用于传递信息

@Data
public class JsonResult {
    private boolean success = true;   //标志是否成功
    private String message;    //返回的信息

    //如果成功,直接new对象返回,不需要加message
    //如果失败,写下边的方法
    public void mark(String msg){
        this.success = false;
        this.message = msg;
    }
}

MyAuthcFilter:继承与FormAuthenticationFilter

@Component("authcFilter")
public class MyAuthcFilter extends FormAuthenticationFilter {
    
    //登陆成功,响应json
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("text/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        JsonResult jsonResult = new JsonResult();
        writer.write(JSON.toJSONString(jsonResult));

        return false;
    }
    //登陆失败。,响应json
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        response.setContentType("text/json;charset=utf-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        JsonResult jsonResult = new JsonResult();
        jsonResult.mark("亲,您的账号密码输入有误,请重新输入!");
        writer.write(JSON.toJSONString(jsonResult));

        return false;
    }
}
  • 总结
    ShiroFilter进行拦截->DelegatingSubject开始执行login方法->login方法调用SecurityManager.login->调用权限认证器->调用MyRealm进行认证,返回正确认证信息->DelegatingSubject的login方法执行结束->执行我们自定义定义的MyauthcFilter的方法,响应成功或失败的json数据
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值