Results 1 to 10 of 10

Thread: Catch accessDeniedException

  1. #1
    Join Date
    Jan 2010
    Posts
    14

    Default Catch accessDeniedException

    Hi!
    I have just started to log all of my application events and store it to a db.
    I ran in to some trouble when trying to log all accessDeniedExceptions thrown by Spring Security.

    Is there any good way in one place to deal with my serviceobjects that may throw this exception.

    Thank you very much!

  2. #2

    Default Catch accessDeniedException

    How about having a custom voter that extends the spring sec voters and catch the access denied exception ?

  3. #3
    Join Date
    Jan 2010
    Posts
    14

    Default

    Followed your advice..seems like a good solution

    Thanks!

  4. #4

    Default Catch accessDeniedException

    If you dont want to mix your domain logic into security layer then the alternative could be to implement a AfterThrows advice and apply it to your service layer.

    /Kalyan

  5. #5
    Join Date
    Jan 2010
    Posts
    14

    Default

    thanx for your quick reply. I'm trying to implement my custom RoleVoter as follows.

    Code:
    public class KmsRoleVoter implements AccessDecisionVoter {
    
    	private String rolePrefix = "ROLE_";
    
    	@Override
    	public boolean supports(ConfigAttribute attribute)
    	{
    		if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getRolePrefix())) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    
    	@Override
    	public boolean supports(Class<?> clazz) 
    	{
    		return true;
    	}
    
    	@Override
    	public int vote(Authentication authentication, Object object,Collection<ConfigAttribute> attributes) 
    	{
    		int result = ACCESS_ABSTAIN;
    
    		Collection<GrantedAuthority> authorities = extractAuthorities(authentication);
    		for (ConfigAttribute attribute : attributes) {
    			if (this.supports(attribute)) {
    				result = ACCESS_DENIED;
    
    				for (GrantedAuthority authority : authorities) {
    					if (attribute.getAttribute().equals(
    							authority.getAuthority())) {
    						return ACCESS_GRANTED;
    					}
    				}
    			}
    		}
    
    		return result;
    	}
    
    	public void setRolePrefix(String rolePrefix) {
    		this.rolePrefix = rolePrefix;
    	}
    
    	public String getRolePrefix() {
    		return rolePrefix;
    	}
    
    	Collection<GrantedAuthority> extractAuthorities(
    			Authentication authentication) {
    		return authentication.getAuthorities();
    	}
    This config always throws me a 403 error.
    How does this config look to you?
    in my security.xml I added the following lines:

    Code:
    <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
    <!--        <beans:property name="allowIfAllAbstainDecisions" value="false"/>-->
            <beans:property name="decisionVoters">
                <beans:list>
                    <beans:bean class="se.esplanad.kms.core.rest.impl.KmsRoleVoter" />
                </beans:list>
            </beans:property>
        </beans:bean>
    thank you for your help!

  6. #6

    Default Catch accessDeniedException

    I am not sure is it for the same requirement you had earlier where the intention is to catch the AccessDeniedException.

    if so, I am wrong in mentioning that it should be custom voter, I rather mean custom decision manager which is

    public class customDecisionManager extends UnanimousBased {

    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> attributes)
    throws AccessDeniedException {
    try {
    super.decide();
    } catch (AccessDecisionManager e) {
    //do business logic
    throw e;

    }


    }

    }

    And use this decisionManager instead of UnanimousBased in your xml config.

    /Kalyan

  7. #7
    Join Date
    Jan 2010
    Posts
    14

    Default

    I think I solved my problem now..did as you said, using my own customDecisionmanager. but I used the AffirmativeBased instead.

    if I understood it correctly affirmativeBased accessDecisionManager returns access if any AccessDecisionVoter returns an affirmative response.
    so in that case,lets say I have annotated a service with @Secured({"ROLE_USER,"ROLE_ADMIN"})

    If my authenticated user is eaither user or admin it will grant access, am I right?

  8. #8

    Default

    Yes you are right. However in this case of example typically you would use roleHierarchyVoter instead.

    /kalyan

  9. #9
    Join Date
    Jan 2010
    Posts
    14

    Default

    Ok..thanks for the tip. I will take a look at that.

  10. #10
    Join Date
    Mar 2010
    Posts
    1

    Default using @Around for catch accessdeniedexception

    Hi I've solved the same problem using @Around annotation. It's a sample (probably it will be useful for someone):

    Minstrel.java
    ...
    Code:
        @Around(value = "execution(* *.embarkOnQuest(..)) && this(knight)",
                argNames = "joinPoint,knight")
        public HolyGrail actionsOfMinstrel(ProceedingJoinPoint joinPoint, Knight knight)
                throws Throwable{
            SONG.info("Fa la la; Sir " + knight.getName() +
                    " is so brave!");
            try{
                HolyGrail result = (HolyGrail)joinPoint.proceed();
                SONG.info("Tee-hee-he; Sir " + knight.getName() +
                    " did embark on a quest!");
                return result;
            } catch (AccessDeniedException ex){
                SONG.error("The Sir " + knight.getName() +
                    " could not access to the quest! Caused by: " + ex.getMessage());
                return null;
            }
        }
    KnightOfTheRoundTable.java
    ...
    Code:
        public HolyGrail embarkOnQuest() {
            System.out.println("embarking...");
            return quest.embark();
        }
    HolyGrailQuest.java
    ...
    Code:
        @Secured("ROLE_ADMIN")
        public HolyGrail embark() {
        // do whatever it means to embark on a quest
            return new HolyGrail();
        }
    Main.java
    ...
    Code:
        Knight knight1 = (Knight)factory.getBean("knight1");
        Knight knight2 = (Knight)factory.getBean("knight2");
        Knight knight3 = (Knight)factory.getBean("knight3");
        AuthenticationManager am = (AuthenticationManager)factory.getBean("am");
    
        authenticateKnight(knight1,am);
        authenticateKnight(knight2,am);
        authenticateKnight(knight3,am);
    
        knight1.embarkOnQuest();
        knight1.embarkOnQuest();
        knight1.embarkOnQuest();
    application-context.xml
    ...
    Code:
        <bean id="knight1" class="ru.sgu.Knight.Java.KnightOfTheRoundTable">
            <constructor-arg value="arthur1"/>
        </bean>
    	<bean id="knight2" class="ru.sgu.Knight.Java.KnightOfTheRoundTable">
            <constructor-arg value="arthur2"/>
        </bean>
        <bean id="knight3" class="ru.sgu.Knight.Java.KnightOfTheRoundTable">
            <constructor-arg value="arthur3"/>
        </bean>
    	
        <security:global-method-security secured-annotations="enabled" />
    
        <security:authentication-manager alias="am">
            <security:authentication-provider>
                <security:user-service>
                    <security:user name="arthur1" password="arthur1" authorities="ROLE_USER, ROLE_ADMIN" />
                    <security:user name="arthur2" password="arthur2" authorities="ROLE_USER" />
                </security:user-service>
            </security:authentication-provider>
        </security:authentication-manager>
    Last edited by azotcsit; May 10th, 2010 at 05:00 AM. Reason: addings [code][/code] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •