-
FEATURED COMPONENTS
First time here? Check out the FAQ!
1 | initial version | |
Have you downloaded the sample app consists of their two projects?
Here are the security xml: You can see that i have declared an other authentication-provider.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring namespace-based configuration -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:zksp="http://www.zkoss.org/2008/zkspring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.zkoss.org/2008/zkspring http://www.zkoss.org/2008/zkspring/zkspring.xsd">
<!-- Enable the @Secured annotation to secure service layer methods -->
<global-method-security secured-annotations="enabled" />
<http auto-config="true">
<!-- ### If we have our own LoginPage. So we must ### -->
<!-- ### tell Spring the name and the place. ### -->
<!-- ### In our case we take the same page ### -->
<!-- ### for a error message by a failure. ### -->
<!-- ### Further the page after a successfully login. ### -->
<form-login login-page="/zkloginDialog.zul"
authentication-failure-url="/zkloginDialog.zul?login_error=1"
default-target-url="/pages/index.zul" />
<!-- ### Tell Spring where it goes after logout. ### -->
<!-- ### logout-url is a action url. ### -->
<logout logout-url="/j_spring_logout" logout-success-url="/index.zul" />
<!-- ### Define the pages that are to be intercepted ### -->
<!-- ### It is parsed from top to bottom. Means that ### -->
<!-- ### the most specific pattern is standing on TOP ### -->
<!-- ### and the CATCH ALL is on BOTTOM! ### -->
<intercept-url pattern="/pages/**" access="IS_AUTHENTICATED_REMEMBERED" />
<intercept-url pattern="/WEB-INF/pages/**" access="IS_AUTHENTICATED_REMEMBERED" />
<!-- ### The root page is accessible by everyone but ### -->
<!-- ### internally spring makes a login and ### -->
<!-- ### this user becames a UserDetails ### -->
<!-- ### (in there are the ip-address and others) ### -->
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- ### Per user one session !! ### -->
<concurrent-session-control max-sessions="1" />
</http>
<!-- ### We define the kind of authentification with a ### -->
<!-- ### so called authentication-provider ### -->
<!-- ### So we have our users stored in a DB we use ### -->
<!-- ### our own user-service class and point to her. ### -->
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>
<!-- ### The Implementation of the Interface ### -->
<!-- ### UserDetailService for the logged in ### -->
<!-- ### user and his rights ### -->
<beans:bean id="myUserDetailsService" class="de.forsthaus.zksample.policy.PolicyManager">
<beans:property name="userService" ref="userService" />
</beans:bean>
<!-- ### Here, only for showing in the console ### -->
<!-- ### that we catches the events. ### -->
<zksp:zk-event login-template-close-delay="5">
<zksp:intercept-event path="//**/btn_*" event="onClick"
access="IS_AUTHENTICATED_REMEMBERED" />
<zksp:intercept-event path="/**" event="onClick"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
</zksp:zk-event>
<!-- ### This aspect call automatically the methode ### -->
<!-- ### 'loginLogging' which is for writing a log for ### -->
<!-- ### all successfully and failed logins, if a ### -->
<!-- ### methode is called that handles the ### -->
<!-- ### Authentication. ### -->
<beans:bean id="LoginLoggingPolicyService"
class="de.forsthaus.zksample.policy.LoginLoggingPolicyService">
<beans:property name="loginLoggingService" ref="loginLoggingService" />
</beans:bean>
<aop:config>
<aop:aspect id="LoginLoggingAspect" ref="LoginLoggingPolicyService">
<aop:pointcut id="authPointcut"
expression="execution(public org.springframework.security.Authentication org.springframework.security.providers.AuthenticationProvider.authenticate(org.springframework.security.Authentication))" />
<aop:around pointcut-ref="authPointcut" method="loginLogging" />
</aop:aspect>
</aop:config>
</beans:beans>
The important point is the implementation of the Spring-Security Interface UserDetailService which you can find in my app in the PolicyManager class. There is only ONE methode to implement.
@Override
public UserDetails loadUserByUsername(String userId) {
public class PolicyManager implements UserDetailsService, Serializable {
private static final long serialVersionUID = 1L;
private transient final static Logger logger = Logger.getLogger(PolicyManager.class);
private transient UserService userService;
public SecUser getUserByLoginname(final String userName) {
return getUserService().getUserByLoginname(userName);
}
@Override
public UserDetails loadUserByUsername(String userId) {
SecUser user = null;
GrantedAuthority[] grantedAuthorities = null;
try {
user = getUserByLoginname(userId);
if (user == null) {
throw new UsernameNotFoundException("Invalid User");
}
// TEST
String context = user.getUsrLocale(); // i.e. 'en_EN' or 'de_DE'
// if (!StringUtils.isEmpty(context)) {
// Labels.register(new GeneralLabelLocator(context));
// }
grantedAuthorities = getGrantedAuthority(user);
} catch (NumberFormatException e) {
throw new DataRetrievalFailureException("Cannot loadUserByUsername userId:" + userId + " Exception:" + e.getMessage(), e);
}
UserDetails userDetails = new UserImpl(user, grantedAuthorities);
if (logger.isDebugEnabled()) {
logger.debug("Rechte für '" + user.getUsrLoginname() + "' (ID: " + user.getUsrId() + ") ermittelt. ("
+ Arrays.toString(grantedAuthorities) + ") [" + this + "]");
for (GrantedAuthority grantedAuthority : grantedAuthorities) {
logger.debug(grantedAuthority.getAuthority());
}
}
return userDetails;
}
private GrantedAuthority[] getGrantedAuthority(SecUser user) {
List<SecRight> rights = getUserService().getRightsByUser(user);
GrantedAuthority[] grantedAuthorities = null;
grantedAuthorities = new GrantedAuthority[rights.size()];
for (int i = 0; i < rights.size(); i++) {
SecRight right = rights.get(i);
GrantedAuthority authority = new GrantedAuthorityImpl(right.getRigName());
grantedAuthorities* = authority;
}
return grantedAuthorities;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void test() {
System.out.println("PolicyManager.test() -> " + loadUserByUsername("user"));
}
}
The rights i get from the database with the following code which you can find in the backend project.
UserServiceImpl.java
@Override
public List<SecRight> getRightsByUser(SecUser user) {
List rightList = new ArrayList<SecRight>();
// 1. erst die zum User zugeteilten Rollen ermitteln
// 1. First get the roles that are attached to a user
List<SecRole> listRoles = new ArrayList<SecRole>();
listRoles = getRolesByUser(user);
if (logger.isDebugEnabled()) {
if (listRoles != null) {
for (SecRole secRole : listRoles) {
logger.info(secRole.getRolShortdescription());
}
}
}
// 2. die zu den Rollen die zugehörigen Gruppen ermitteln
// 2. get the groups that belongs to the roles
List<SecGroup> listGroup = new ArrayList<SecGroup>();
if (listRoles != null) {
for (SecRole role : listRoles) {
List<SecGroup> tmpListGroup = new ArrayList<SecGroup>();
tmpListGroup = getSecRolegroupDAO().getGroupsByRole(role);
if (tmpListGroup != null) {
for (SecGroup secGroup : tmpListGroup) {
listGroup.add(secGroup);
}
}
}
}
if (logger.isDebugEnabled()) {
if (listGroup != null) {
for (SecGroup secGroup : listGroup) {
logger.info(secGroup.getGrpShortdescription());
}
}
}
// 3. zu den Gruppen die zugeordneten Rechte ermitteln
// 3. get the rights that belongs to the groups
List<SecRight> listRight = new ArrayList<SecRight>();
if (listGroup != null) {
for (SecGroup group : listGroup) {
List<SecRight> tmpListRight = new ArrayList<SecRight>();
tmpListRight = getSecGrouprightDAO().getRightsByGroup(group);
if (tmpListRight != null) {
for (SecRight secRight : tmpListRight) {
listRight.add(secRight);
}
}
}
}
if (logger.isDebugEnabled()) {
if (listRight != null) {
for (SecRight secRight : listRight) {
logger.info(secRight.getRigName());
}
}
}
// 4. Doppelte Rechte unterdrücken
// 4. filter double rights out
if (listRight != null) {
List decorateList = SetUniqueList.decorate(rightList);
for (int i = 0; i < listRight.size(); i++) {
decorateList.add(listRight.get(i));
}
}
if (logger.isDebugEnabled()) {
logger.info("--> Decorated List");
if (rightList != null) {
for (SecRight secRight : (List<SecRight>) rightList) {
logger.info(secRight.getRigName());
}
}
}
return rightList;
}
regards Stephan