您的位置:首页 > 其它

shiro框架---解决权限限制问题

2015-10-26 00:00 232 查看

shiro简介



ApacheShiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证,授权,企业会话管理和加密(核心功能)。

以下是你可以用ApacheShiro所做的事情:

1.验证用户

2.对用户执行访问控制,如:

判断用户是否拥有角色admin。

判断用户是否拥有访问的权限

3.在任何环境下使用SessionAPI。例如CS程序。

4.可以使用多个用户数据源。例如一个是oracle用户库,另外一个是mysql用户库。

5.单点登录(SSO)功能。

6.“RememberMe”服务,类似购物车的功能,shiro官方建议开启

shiro框架执行流程



ApplicationCode:应用程序代码,由开发人员负责开发

subject:主体,当前用户

securitymanager:安全管理器,框架的核心,负责调用realm,框架提供

realm:类似于dao,访问安全数据(权限、角色、用户),框架提供,也可以自定义

权限控制方式:

方式一:URL拦截方式



第一步:导包



第二步:在web.xml里面配置由spring框架提供整合shero的过滤器

1

2

3

4

5

6

7

8

9

10

11

12

13

3ff0

14

15

16

17

18

19
<!--指定spring配置文件-->

<
context-param
>


<
param-name
>contextConfigLocation</
param-name
>


<
param-value
>classpath:applicationContext.xml</
param-value
>

</
context-param
>

<
listener
>


<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>

</
listener
>

<!--配置权限管理-->

<
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
>
第三步:在applicationContext.xml里面配置一个bean,并且id要和过滤器的名字一样

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
<!--第一种代码配置设置shiro权限-->


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


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


<
property
name
=
"loginUrl"
value
=
"/login.jsp"
></
property
>


<
property
name
=
"successUrl"
value
=
"/index.jsp"
></
property
>


<
property
name
=
"unauthorizedUrl"
value
=
"/500.jsp"
></
property
>


<
property
name
=
"filterChainDefinitions"
>


<
value
>


/css/**=anon


/js/**=anon


/images/**=anon


/login.jsp*=anon


/validatecode.jsp*=anon


/UserAction_login.action*=anon


/page_base_staff.action=perms["staff"]


/**=authc


</
value
>


</
property
>


</
bean
>
第四步:在applicationConte.xml里面配置安全管理器,并且注入Realm

1

2

3

4

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


<
property
name
=
"realms"
ref
=
"shiroRealms"
></
property
>


<
property
name
=
"cacheManager"
ref
=
"cache"
></
property
>


</
bean
>


<
bean
id
=
"shiroRealms"
class
=
"com.mickeymouse.bos.shiro.ShiroRealms"
></
bean
>
第五步:编写一个realm

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

3ff0

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76
package
com.mickeymouse.bos.shiro;

import
java.util.List;

import
javax.annotation.Resource;

import
org.apache.shiro.authc.AuthenticationException;

import
org.apache.shiro.authc.AuthenticationInfo;

import
org.apache.shiro.authc.AuthenticationToken;

import
org.apache.shiro.authc.SimpleAuthenticationInfo;

import
org.apache.shiro.authc.UsernamePasswordToken;

import
org.apache.shiro.authz.AuthorizationInfo;

import
org.apache.shiro.authz.SimpleAuthorizationInfo;

import
org.apache.shiro.realm.AuthorizingRealm;

import
org.apache.shiro.subject.PrincipalCollection;

import
org.springframework.beans.factory.annotation.Autowired;

import
com.mickeymouse.bos.dao.IFunctionDao;

import
com.mickeymouse.bos.dao.IUserDao;

import
com.mickeymouse.bos.domain.Function;

import
com.mickeymouse.bos.domain.User;

public
class
ShiroRealms
extends
AuthorizingRealm{


@Autowired


private
IUserDaoiUserDao;


@Resource


private
IFunctionDaoiFunctionDao;


/**


*授权


*/


@Override


protected
AuthorizationInfodoGetAuthorizationInfo(


PrincipalCollectionprincipals){


//获取认证信息


SimpleAuthorizationInfoauthorizationInfo=
new
SimpleAuthorizationInfo();


//通过认证信息获取当前用户


Useruser=(User)principals.getPrimaryPrincipal();


//先判断是不是超管


if
(user.getUsername()==
"admin"
){


//超管:直接查询所有权限


List<Function>list=iFunctionDao.findAll();


for
(Function
function
:list){


authorizationInfo.addStringPermission(
function
.getCode());


}


}
else
{


//普通用户:通过用户ID查询所具有的权限


List<Function>list=iFunctionDao.findFunctionByUserid(user.getId());


for
(Function
function
:list){


authorizationInfo.addStringPermission(
function
.getCode());


}


}


return
authorizationInfo;


}


/**


*认证:判断用户名与密码是否正确


*/


@Override


protected
AuthenticationInfodoGetAuthenticationInfo(


AuthenticationTokentoken)throwsAuthenticationException{


//通过认证标记获取传入的用户名


UsernamePasswordTokenusernamePasswordToken=(UsernamePasswordToken)token;


String
username=usernamePasswordToken.getUsername();


//通过用户名查询数据库返回对象


Useruser=iUserDao.findByUserFronUsername(username);


if
(user==
null
){


//如果为空直接返回null,此时subject会直接抛出异常


return
null
;


}
else
{


//账号存在,将从数据库中查询出的密码交给安全管理器比对


//三个参数:第一个验证正确后需要的返回值,第二个:安全管理器需要的比对密码,第三个:realm的类名


//简单认证信息对象


AuthenticationInfoauthenticationInfo=
new
SimpleAuthenticationInfo(user,user.getPassword(),
this
.getName());


return
authenticationInfo;


}


}

}
第六步:使用shero框架完成登录

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35
/**


*登录


*@return


*/

public
String
login(){


String
key=(
String
)ActionContext.getContext().getSession().
get
(
"key"
);


//取出用户名密码为空


if
(!StringUtils.isEmpty(t.getUsername())&&!StringUtils.isEmpty(t.getPassword())){


//去除验证码错误或空


if
(!StringUtils.isEmpty(checkcode)&&!StringUtils.isEmpty(key)&&key.equals(checkcode)){


//获取当前用户,此时的状态为"未认证"


Subjectsubject=SecurityUtils.getSubject();


//创建用户名和密码的认证标记


AuthenticationTokenauthenticationToken=
new
UsernamePasswordToken(t.getUsername(),MD5Utils.md5(t.getPassword()));


try
{


//调用登录方法,传入认证标记


subject.login(authenticationToken);


//如果没有异常,那么返回"认证信息传出的返回值对象"


Useruser=(User)subject.getPrincipal();


//存入session域中


ActionContext.getContext().getSession().put(
"User"
,user);


return
"home"
;


}
catch
(Exceptione){


e.printStackTrace();


this
.addActionMessage(
"用户名或者密码不正确~"
);


}


}
else
{


this
.addActionMessage(
"验证码错误!"
);


}


}
else
{




this
.addActionMessage(
"用户名或者密码不能为空!"
);


}


return
"login"
;

}
异常信息:

当用户名错误,认证信息为空抛出异常



当密码错误,安全管理器抛出异常



方式二:注解方式



第一步:导包

第二步:在applicationContext.xml里开启shero注解

1

2

3

4

5

6
<!--第二种:注解方式设置shiro权限-->


<!--
1
.开启shiro注解-->


<beanid=
"defaultAdvisorAutoProxyCreator"
class
=
"org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
>


<propertyname=
"proxyTargetClass"
value=
"true"
></property>


</bean>


<bean
class
=
"org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"
></bean>
第三步:在Action的方法上使用shiro注解描述需要具有的权限

1

2

3

4

5

6

7

8

9

10

11
/**


*分页查询


*/

@RequiresPermissions
(value=
"region"
)
//执行这个方法需要具有region.query这个权限

@RequiresRoles
(value=
"admin"
)

public
StringpageQuery(){


regionService.pageQuery(pageBean);


String[]excludes=
new
String[]{
"subareas"
};


this
.writePageBean2Json(pageBean,excludes);


return
NONE;

}
第四步:注意修改action抽取类的构造方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28
public
ActionBase(){




ParameterizedTypeparameterizedType=
null
;


TypegenericSuperclass=
this
.getClass().getGenericSuperclass();

&n
3ff0
bsp;
if
(genericSuperclass
instanceof
ParameterizedType){


parameterizedType=(ParameterizedType)
this
.getClass().getGenericSuperclass();


}
else
{


//这里的this为shero的代理对象


parameterizedType=(ParameterizedType)
this
.getClass().getSuperclass().getGenericSuperclass();


}











//获得BaseAction类定义的泛型数组


Type[]types=parameterizedType.getActualTypeArguments();


Class<T>class1=(Class<T>)types[
0
];


try
{


t=class1.newInstance();


}
catch
(InstantiationExceptione){


//TODOAuto-generatedcatchblock


e.printStackTrace();


}
catch
(IllegalAccessExceptione){


//TODOAuto-generatedcatchblock


e.printStackTrace();


}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: