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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With