菜园子

BlogJava 首页 新随笔 联系 聚合 管理
  7 Posts :: 1 Stories :: 31 Comments :: 0 Trackbacks

Shiro权限框架

开发系统中,少不了权限,目前java里的权限框架有SpringSecurity和Shiro(以前叫做jsecurity),对于SpringSecurity:功能太过强大以至于功能比较分散,使用起来也比较复杂,跟Spring结合的比较好。对于初学Spring Security者来说,曲线还是较大,需要深入学习其源码和框架,配置起来也需要费比较大的力气,扩展性也不是特别强。

对于新秀Shiro来说,好评还是比较多的,使用起来比较简单,功能也足够强大,扩展性也较好。听说连Spring的官方都不用Spring Security,用的是Shiro,足见Shiro的优秀。网上找到两篇介绍:http://www.infoq.com/cn/articles/apache-shiro http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/,官网http://shiro.apache.org/ ,使用和配置起来还是比较简单。下面只是简单介绍下我们是如何配置和使用Shiro的(暂时只用到了Shiro的一部分,没有配置shiro.ini文件)。

首先是添加过滤器,在web.xml中:

<filter>

<filter-name>shiroFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

<init-param>

            <param-name>targetFilterLifecycle</param-name>

            <param-value>true</param-value>

     </init-param>

</filter>    

<filter-mapping>

<filter-name>shiroFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

权限的认证类:

public class ShiroDbRealm extends AuthorizingRealm {

    @Inject

    private UserService userService ;

    

    /**

 * 认证回调函数,登录时调用.

 */

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) 
throws AuthenticationException {

UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

User useruserService.getUserByUserId(token.getUsername());

if (user!= null) {  

    return new SimpleAuthenticationInfo(user.getUserId(), user.getUserId(), getName());

else {

return null;

}

}

/**

 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.

 */

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

String loginName = (String) principals.fromRealm(getName()).iterator().next();

User useruserService.getUserByUserId(loginName);

if (user != null) {

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

info.addStringPermission("common-user");

return info;

else {

return null;

}

}

}

Spring的配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<beans >

<description>Shiro Configuration</description>

<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

<property name="realm" ref="shiroDbRealm" />

</bean>

<bean id="shiroDbRealm" class="com.company.service.common.shiro.ShiroDbRealm" />

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        <property name="securityManager" ref="securityManager"/>

        <property name="loginUrl" value="/common/security/login" />

        <property name="successUrl" value="/common/security/welcome" />

        <property name="unauthorizedUrl" value="/common/security/unauthorized"/>

        <property name="filterChainDefinitions">

            <value>

                /resources/** = anon

                /manageUsers = perms[user:manage]

                /** = authc

            </value>

        </property>

    </bean>

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>

    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

        <property name="securityManager" ref="securityManager"/>

    </bean>

</beans>

登录的Controller:

@Controller

@RequestMapping(value = "/common/security/*")

public class SecurityController {

    @Inject

    private UserService userService;

    @RequestMapping(value = "/login")

    public String login(String loginName, String password,
HttpServletResponse response, HttpServletRequest request) throws Exception {

        User user = userService.getUserByLogin(loginName);

            if (null != user) {

                setLogin(loginInfoVO.getUserId(), loginInfoVO.getUserId());

                return "redirect:/common/security/welcome";

            } else {

                return "redirect:/common/path?path=showLogin";

            }

    };

    public static final void setLogin(String userId, String password) {

        Subject currentUser = SecurityUtils.getSubject();

        if (!currentUser.isAuthenticated()) {

            //collect user principals and credentials in a gui specific manner 

            //such as username/password html form, X509 certificate, OpenID, etc.

            //We'll use the username/password example here since it is the most common.

            //(do you know what movie this is from? ;)

            UsernamePasswordToken token = new UsernamePasswordToken(userId, password);

            //this is all you have to do to support 'remember me' (no config - built in!):

            token.setRememberMe(true);

            currentUser.login(token);

        }

    };

    

    @RequestMapping(value="/logout")

    @ResponseBody

    public void logout(HttpServletRequest request){

        Subject subject = SecurityUtils.getSubject();

        if (subject != null) {           

            subject.logout();

        }

        request.getSession().invalidate();

    };

}

注册和获取当前登录用户:

    public static final void setCurrentUser(User user) {

        Subject currentUser = SecurityUtils.getSubject();

        if (null != currentUser) {

            Session session = currentUser.getSession();

            if (null != session) {

                session.setAttribute(Constants.CURRENT_USER, user);

            }

        }

    };

    public static final User getCurrentUser() {

        Subject currentUser = SecurityUtils.getSubject();

        if (null != currentUser) {

            Session session = currentUser.getSession();

            if (null != session) {

                User user = (User) session.getAttribute(Constants.CURRENT_USER);

                if(null != user){

                    return user;

                }

}

}

    };

需要的jar包有3个:shiro-core.jar,shiro-spring.jar,shiro-web.jar。感觉shiro用起来比SpringSecurity简单很多。



QQ:24889356
posted on 2011-09-16 21:36 GhostZhang 阅读(32396) 评论(14)  编辑  收藏

Feedback

# re: Shiro权限框架 2011-09-17 08:55 tb
恩 比较不错   回复  更多评论
  

# re: Shiro权限框架 2011-09-17 17:20 rox
正好在看appfuse和springside4的样例,谢谢了。  回复  更多评论
  

# re: Shiro权限框架 2011-09-17 22:59 wison
我现在唯一还有疑问的就是,这个数据库表中的字段,怎么设计。怎么查询出来。望楼主解释。3Q  回复  更多评论
  

# re: Shiro权限框架 2011-09-18 07:58 GhostZhang
这个只是系统权限,不是业务权限。所以表设计的话,我猜你指的是业务权限的表设计吧。shiro不涉及。  回复  更多评论
  

# re: Shiro权限框架 2011-09-19 09:22 wison
@GhostZhang
嗯,我说的是业务权限表的设计,好吧,我们不谈权限设置。仅仅谈登录,登录总需要获得帐号密码,和数据库中的比对吧。如何验证,不清楚是需要我们自己去写还是shiro已经封装好了。我仅仅是不清楚这个地方。3Q楼主。  回复  更多评论
  

# re: Shiro权限框架 2011-09-19 14:27 GhostZhang
@wison
这个需要自己写。  回复  更多评论
  

# re: Shiro权限框架 2011-09-20 09:22 wison
@GhostZhang
OK,3Q  回复  更多评论
  

# re: Shiro权限框架 2012-02-29 22:50 唐文韬
你好,我在整合shiro和spring的过程中,我只要给control加@RequiresAuthentication 类似的这种注解,在项目启动的时候就报错
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)
at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 35 more

可是当我把cglib.jar的包加进去的时候还是报错,期待您的解答  回复  更多评论
  

# re: Shiro权限框架[未登录] 2012-03-04 09:30 ghostzhang
cglib-nodep-2.2.jar
我用的是这个,添加@RequiresAuthentication,启动没问题。  回复  更多评论
  

# re: Shiro权限框架 2012-04-25 16:37 wgw
@唐文韬

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" /> <!-- 和struts结合使用必须把该属性设置为true,否则使用注解出错 -->
</bean>
OK  回复  更多评论
  

# re: Shiro权限框架 2014-03-11 13:09 JSON
页面怎么获取session  回复  更多评论
  

# re: Shiro权限框架[未登录] 2015-12-05 15:34 1
1111  回复  更多评论
  

# re: Shiro权限框架 2016-03-21 14:58 11
32  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: