当前位置: 首页 > 工具软件 > Seam Security > 使用案例 >

seam从登陆开始的安全权限框架理解

冀弘济
2023-12-01

1、对于seam的安全框架和权限控制一直不是很清楚,这几天专门学习了一下。seam使用登录时,一般讲登录名suername和passward绑定到#{credentials}组件中的suername和passward,然后登录按钮绑定到内置的#{identity}组件的loggin方法。这两个组件要要注意的是他们的作用于是HTTP会话,也就是说一旦用户登录,他就保持状态一直到结束即logout,这个细节很重要。
2、indentity的loggin方法是调用的自定义的一个(一般是自定义的实现灵活,不过大致思路相等)验证器里的验证方法(authenticate())。一开始一直没有理解这个authenticate方法,自己思考后才明白。下面是实例代码:
@Name("authenticator")
public class authenticatorAction implements Authenticator {
	@In 
	EntittyManager entityManager;

	@In 
	Credentials credentials ;


	@In
	Identity identity; 

	@In(require=false)
	@Out(require=false , scope=SESSION)
	Member member ;
	public boolean authenticate () {
		List result  = entityManager.createQuery("select m form Member m where m.username=:username and m.password=:passsword")
		.setParameter("username" , identity.getCredentials().getUsername()).
		setParameter("password" , identity.getCredentials().getPassword()).getResultList();
		if (result.size() == 0){
			return false ;
		}
		else
		{
			Member member = (Member) result.get(0);
			Department dpt = (Department) member.getDepartment();


			if( !member.getRoles().inEmpty()) {  //The relationship of  table member and role is many to many,so then will be a Entity declartion
				// a member would have many role.
				for (Role role : member.getRoles()) {
					identity.addRole(role.getName());
				}
			}
			return true;
		}
	}
}


这个验证方法对我来说感觉比较重要,所以对其中的几个点记录一下:
(1)、按照读程序的顺序来看,首先需要关注的是注解及其属性,这个不多说了。
(2)、authenticate验证方法,首先通过注入进来的entityManager的createQuery方法构造语句,把登陆页面时候用户填的用户名和密码的值(通过注入进来的identity组件来获取,其实username和password只已经传到了identity中了)传进来当做对数据库的查询条件,这里用的是命名参数的方法,这样比较安全,是EJB为了防止SQL注入采用的方式。然后如果没有搜索结果就返回false,拒绝登陆。如果有结果,就取出符合条件的第一个对象,(result.get(0);)
(3)、取出对象之后,使用member实体的getRoles方法,取得这个登陆着的角色,如果不是空的话,就用for-each循环遍历,在遍历中执行的语句一开始我不是很理解,现在明白了。就是将对象的所有角色都保存到indentity的角色中,让程序知道当前这个登陆者有什么角色,因为以上来就说了identity和authenticator状态是从一开始保持到结束的。我们在登陆之后会使用的s:hasRole方法就是调用的identity组件的hasRole()方法,我们在验证方法里addRole之后就可以利用hasRole方法进行一定的权限控制了!!!
(4)、在调用member的getRoles()方法时,要关注的是实体中的写法,关于多对多的映射理解与实体映射写法!!!
(5)、因为使用了自定义的验证方法, 所以需要在配置文件中声明用自己的authenticate方法。。。。具体在resources/WEB-INF/components.xml中加上如下的配置

 <security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>

(6)、改程序应当放到src/..../action/目录里面

(7)、可以使这阅读seam的源代码加深理解。


===================================以上为登陆的控制,以下是登陆后的访问控制=============================================================


主要有三种施加约束xml配置文件,注解, jsf EL表达式。
1、直接上例子!例如:
<pages>
	<page view-id= "/password.xhtml" login-requred="true">
	</page>
	<page view-id="/rewads/*" login-requred="true">
	</page>
	<page view-id="/rewads/*" >
		<description>Rewards Summay</description>
		<restrict>#{hasRole('rewardsuser')}</restrict>
	</page>
	
	<!--如果想用户登陆之后重定向到最初请求页面使用如下配置-->
	<event type="org.jboss.seam.security.notLoggedIn">
  		<action execute="#{redirect.captureCurrentView}"/>
 	</event>
 	<event type="org.jboss.seam.security.loginSuccessful">
  		<action execute="#{redirect.returnToCapturedView}"/>
 	</event>
</pages>



2、在页面中使用rendered属性结合是s:hasRole和s:hasPerssion
3、组件访问控制 通过@Resrict注解可以在组件或者组件的方法上设置权限,例如@Restrict("#{identity.loggedIn}") 或者在方法上使用@Restrict(#{s:hasRole('rewaduser')})


4、身份管理
使用JpaIdentityStore注入到IdentityManager中来管理身份,在用户实体中使用@UserPrincipal  @UserPassword   @UserRoles来标记用户的用户名,密码和用户角色色(只能为list或者set)。在角色实体使用@RoleName来标记角色名称。
并且需要在components.xml 中使用配置JpaIdentityStre 
<security:jpa-identity-store entitty-manager="#{entityManager}"
user-class="org.jboss.seam.example.booking.MemberAccount"
role-class="org-jboss-sea.example.booking.MemberRole">


5、其它功能




还有基于规则的安全框架等其他的seam安全知识,,进一步了解请看推荐的书


推荐学习seam的两本书《seam in action》《Seam Framework Web 开发宝典》



 类似资料: