0

I am using spring basic authentication with the following settings in my security xml:

<http use-expressions="true" create-session="never" >
        <intercept-url pattern="/**" method="GET" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="POST" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="PUT" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="DELETE" access="isAuthenticated()" />
        <http-basic />
    </http>

If authentication fails, the browser pop ups a prompt window to renter the user name and password. Is there any way to make that prompt not pop up at all ?

BlackEagle
  • 814
  • 2
  • 12
  • 13

3 Answers3

1

Most probable the page that is used for authentication failure is also protected. You can try manually to set the failure page to one that is not protected like

 <access-denied-handler error-page="/login.jsp"/> 

together with

 <intercept-url pattern="/*login*" access="hasRole('ROLE_ANONYMOUS')"/>

or

<intercept-url pattern='/*login*' filters='none'/>  

or you can use the auto-config='true' attribute of the http element that will fix that for you.See more here

dimcookies
  • 1,930
  • 7
  • 31
  • 37
  • Thanks @enterlezi . I've tried adding filters='none' and tried to add the auto-config as well to the http element, but it didnt work. As far as I understand, the prompt is appearing as a result of the **WWW-Authenticate: Basic realm="Spring Security Application"** in the header of the response. Is there a way to modify the headers of the response? – BlackEagle Apr 27 '12 at 10:13
  • I have no clue about the header but i think the problem is that the authentication failure url is still protected. Try adding a form-login element in your http definition, for example `` and replace with your pages (login.jsp). Also ensure that that page is excluded from filters using access="hasRole('ROLE_ANONYMOUS') since you have specified use-expressions="true" – dimcookies Apr 27 '12 at 10:51
  • The problem is that I am not developing the client pages. I'm creating rest APIs that use basic authentication. So i dont really have any failure urls to redirect to. Do you know if there is a way where I can catch the failure in a handler and there I can control the headers of the response? – BlackEagle Apr 27 '12 at 11:02
  • Ok now it makes sence. Check this answer http://stackoverflow.com/questions/4397062/handle-unauthorized-error-message-for-basic-authentication-in-spring-security if it helps. – dimcookies Apr 27 '12 at 12:01
  • Thanks a lot. I've tuned it as the guy in that link did, and it worked. Thanks a lot for your help! very much appreciated. – BlackEagle Apr 27 '12 at 13:10
0

I have also had the same problem for the REST API throwing login dialog in the browser. As you have told , when the browser sees the response header as

WWW-Authenticate: Basic realm="Spring Security Application

It will prompt with a basic authentication dialog.For REST API based login , this is not ideal. Here is how I did it.Define a custom authentication entry point and in the commence set the header as "FormBased"

response.setHeader("WWW-Authenticate", "FormBased");

application-context.xml configuration below

<security:http create-session="never" entry-point-ref="authenticationEntryPoint" authentication-manager-ref="authenticationManager">
    <security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
    <security:intercept-url pattern="/api/**" access="ROLE_USER" />
</security:http>

<bean id="authenticationEntryPoint" class="com.tito.demo.workflow.security.RestAuthenticationEntryPoint">
</bean>

Custom entry point class below.

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private static Logger logger = Logger.getLogger(RestAuthenticationEntryPoint.class);

    public void commence( HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException ) throws IOException {
        logger.debug("<--- Inside authentication entry point --->");
        // this is very important for a REST based API login. 
        // WWW-Authenticate header should be set as FormBased , else browser will show login dialog with realm
        response.setHeader("WWW-Authenticate", "FormBased");
        response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
    }


}

Note: I have used spring 3.2.5.Release

Now when the rest API is hit from a restclient like POSTMAN , the server will return 401 Unauthorized.

Tito
  • 8,894
  • 12
  • 52
  • 86
0

I have faced the same issue and what I did is create a custom RequestMatcher in my resource server. This prevents Outh2 from sending WWW-Authenticate header.

Example:

 @Override

    public void configure(HttpSecurity http) throws Exception {
         http.requestMatcher(new OAuthRequestedMatcher())
                .authorizeRequests()
                 .antMatchers(HttpMethod.OPTIONS).permitAll()
                    .anyRequest().authenticated();
    }

    private static class OAuthRequestedMatcher implements RequestMatcher {
        public boolean matches(HttpServletRequest request) {
            String auth = request.getHeader("Authorization");
            boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
            boolean haveAccessToken = request.getParameter("access_token")!=null;
   return haveOauth2Token || haveAccessToken;
        }
    }
mx0
  • 6,445
  • 12
  • 49
  • 54
MUNGAI NJOROGE
  • 1,144
  • 1
  • 12
  • 25