Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails spring security core plugin: how to remove the browser prompt for an ajax request

I set up a fresh grails application (2.3.5) and installed the spring security core plugin (2.0-RC2)

I added the following configuration (my 'secure/**' urlmappings use the basicAuthenicationFilter):

  grails.plugin.springsecurity.logout.postOnly = false 
    grails.plugin.springsecurity.rejectIfNoRule = true
    grails.plugin.springsecurity.fii.rejectPublicInvocations = false
    //Enable Basic Auth Filter
    grails.plugin.springsecurity.useBasicAuth = true
    grails.plugin.springsecurity.basic.realmName = "Example"
    grails.plugin.springsecurity.filterChain.chainMap = [
            '/secure/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
            'app/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
    ]



grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.car.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.car.UserRole'
grails.plugin.springsecurity.authority.className = 'com.car.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
   '/app/**':                        ['permitAll'],
   '/index':                         ['permitAll'],
    '/index.gsp':                     ['permitAll'],
    '/**/js/**':                      ['permitAll'],
    '/**/css/**':                     ['permitAll'],
    '/**/images/**':                  ['permitAll'],
    '/**/favicon.ico':                ['permitAll']
]

I have an angular application in the web-app folder. Basically when I make an ajax request from it and supply a bad password in the basic authentication header - I am prompted with a default browser prompt. The request is still pending. I am new to understanding this, but I it looks like the code that is intercepting the request has logic to prompt if the header is not present or invalid.

I am sure I must be missing something obvious, there must be an easy way to configure the behavior for the request. Is there such a configuration? Or am I supposed to create a custom filter?

like image 400
user648869 Avatar asked Jan 30 '14 19:01

user648869


1 Answers

In this case as HTTP Basic Authentication is being used (useBasicAuth = true), the server returns a 401 reply with WWW-Authenticate: Basic, to which the browser replies with a popup for username and password.

That behaviour is present in all browsers and cannot be changed, but there are several alternatives. To avoid the popup we can't use Basic Authentication, but some other mechanism.

The simplest way is to use another header other than the Authorization header (used in Basic authentication) to pass the credentials.

To configure spring security to look for credentials on this new header, have a a look at the 17.2.1 section Request-Header Authentication, where an example is given of how to configure a RequestHeaderAuthenticationFilter to look into a given header.

This is how the configuration looks for using a header named X-MyCustomHeader to pass the credentials:

  <security:http>
    <!-- Additional http configuration omitted -->
    <security:custom-filter position="PRE_AUTH_FILTER" ref="customAuthFilter" />
  </security:http>

    <bean id="customAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="X-MyCustomHeader"/>
    <property name="authenticationManager" ref="authenticationManager" />
  </bean>

  <bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService">
      <bean id="userDetailsServiceWrapper"
          class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
        <property name="userDetailsService" ref="userDetailsService"/>
      </bean>
    </property>
    </bean>

    <security:authentication-manager alias="authenticationManager">
      <security:authentication-provider ref="preauthAuthProvider" />
    </security:authentication-manager>

In general for frontend applications is better not to use basic authentication, as browsers cache those credentials making such an application vulnerable to request forgery (CSRF) attacks.

like image 185
Angular University Avatar answered Oct 29 '22 15:10

Angular University