Announcement Announcement Module
Collapse
No announcement yet.
Catch accessDeniedException Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Catch accessDeniedException

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

    Comment


    • #3
      Followed your advice..seems like a good solution

      Thanks!

      Comment


      • #4
        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

        Comment


        • #5
          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!

          Comment


          • #6
            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

            Comment


            • #7
              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?

              Comment


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

                /kalyan

                Comment


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

                  Comment


                  • #10
                    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, 06:00 AM. Reason: addings [code][/code] tags

                    Comment

                    Working...
                    X