spring controller accept only local requests - spring

Is there any easy way in Spring Security to lock down an #Controller to only accept requests from the same (local) host?
I was looking at this post:
Securing servlet URL without using username password authentication
However, I was wondering if that is actual best practice vs. some other security measure.

You can use hasIpAddress expression in the filter security interceptor.
<http use-expressions="true">
<intercept-url pattern="/**" access="hasIpAddress('127.0.0.1/32')"/>
...
</http>

Related

Spring Security 4: Allowing anonymous access and authenticated access on same url

I have a Jersey 2 application which I'm trying to secure using Spring Security 4 and HTTP Basic authentication.
The controller class is a Spring bean and is injected into the Jersey Rest Resource. I'm using Spring Pre-Post-annotations on the controller's methods and tried out the following configs:
<security:global-method-security pre-post-annotations="enabled" />
<security:http>
<security:http-basic />
<security:intercept-url pattern="/**" access="hasRole('USER')" />
<security:csrf disabled="true"/>
</security:http>
Problem: Works fine with http-basic authenticated users, the annotated methods (#PreAuthorize("hasRole('USER')")) are secured and only work when the correct credentials are provided. BUT: Anonymous access on other resources under /** is not possible anymore (which is correct, but which I want to have).
Using
<security:intercept-url pattern="/**" access="permitAll" />
instead, every user is handled as anonymous, even though they are providing the correct credentials via HTTP Basic. So even a user with the correct role cannot access the annotated method, a AccessDeniedException is thrown.
What I want: Every user should be allowed to access all resources under "/**". If he's authenticated via HTTTP Basic and has sufficient rights, the annotated method can be called. If he's not authenticated or authorized, an AccessDeniedException should be thrown.
How do I have to configure the Spring security <http> section?

Support SAML SSO and normal login

I have an application which is accessed by two types of users, internal and external.
I need to authenticate external users using SAML.
I need to authenticate internal users with the normal form-based login. My application need to support both types of users. I use spring security frame work.
Is it possible to support both types of users? if so can you suggest the approach at high level? Thanks.
You can easily enable support for both form and SAML authentication with configuration similar to this:
<http entry-point-ref="authenticationEntryPoint" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
<form-login login-page="/login" />
<custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</http>
Make sure that your AuthenticationManager contains the samlAuthenticationProvider. And of course include other configuration parts from the Spring SAML sample application.
You can then create your custom login page which presents user with username+password fields for form-based authentication and a link/picture (or multiple of them) which initialize authentication with the IDP (by redirecting user to scheme://host:port/saml/login?idp=selectedIdpEntityId).
Your users then decide which one to use - depending on whether they's internal or external.
The part of Spring SAML documentation touching on this subject is in chapter Spring Security integration.

Public & Private REST APIs with Spring Security

I have a REST Web Service written with Spring 3.2 that is secured with CAS via Spring Security, and I would like to have it provide an identical private, internal API that could be consumed by other servers on our private network without requiring authentication.
For example, these two endpoints /app/public/people/{id} and /app/private/people/{id} would both map to the same handler but the latter would bypass security and the former would require CAS authentication.
Can I just put both in the same #RequestMapping annotation and specify different security intercepts? For example,
security intercepts:
<security:intercept-url pattern="/private/**" access="permitAll() />
<security:intercept-url pattern="/public/**" access="isAuthenticated()" requires-channel="https"/>
request mapping:
#RequestMapping(value={"/public/people/{id}", "/private/people/{id}"})
What about using IP address to distinguish between access from private and public network? Then you can define just one endpoint for both. For an example, if you’re private network is 192.168.1.0/24, then:
<security:intercept-url pattern="/**"
access="isAuthenticated() or hasIpAddress('192.168.1.0/24')"
requires-channel="https" />
If you have Servlet container behind a reverse proxy, don’t forget to set X-Forwarded-For (or X-Real-IP) header and configure your container to use it; otherwise Spring Security will see IP of the reverse proxy, not a client.

Securing REST API with Spring Security

I'm trying to implement a REST API for my Spring application. As there are resources which might not be accessed by everyone, I need a security layer.
Within this application I'm already using Spring Security (which works perfectly fine) for securing my web application.
I've added the following http configuration to my spring-security.xml:
<http pattern = "/api/**" use-expressions = "true" disable-url-rewriting = "true">
<http-basic />
</http>
So I would assume that all request that are made to URLs starting with api/ will be secured.
Problem is that I can access my secured methods without any authentications. But if I use a REST client to access it, I receive this error:
message: Full authentication is required to access this resource
description: This request requires HTTP authentication.
I have no idea how to proceed. What is the best way to secure a REST API using Spring Security?
If you use Spring Security in your application, you, probably, already have an <http> section in one of your Spring config files. You can use this section to secure your REST API.
The <http> does not secure anything on its own. You have to add <intercept-url> rules inside it:
<intercept-url pattern="/api/**" access="hasRole('ROLE_USER')" />
There is a tuto on the official site of Spring. It is a little more complicated :
Official Spring Tuto
Just use Spring Security. In <http> tag add: <security:intercept-url pattern="your url" access="hasAnyRole('Your_User_Role1', 'Your_User_Role2')" />.
Or try use annotations. In your spring-config.xml enable security annotations: <security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" secured-annotations="enabled"/>
and in Controller add #PreAuthorize :
#PreAuthorize("hasAnyRole('Your_User_Role1', 'Your_User_Role2')")
#RequestMapping(value = "/address_planing/load_employee_info")

Spring Security in a Stateless webapp? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
create-session stateless usage
Im just beginning experimenting on Spring Security, on version 3.1, and im wondering how to achieve authentication with a stateless webapp.
http-basic and digest come to mind, and i've tried them, but i dislike the inability to logout like the form authentication without closing the browser.
I currently have a working stateless webapp with form-based authentication using spring security (which makes it stateful by storing auth stuffs in session perhaps ?), and i wonder what are the strategies that i could research on to make spring security work without making use of http sessions ?
I realize that there's a <http create-session="stateless" ..>, but there must be something that needs more doing because the app stops working correctly after i tried that, by keep authenticating me when accessing protected resources.
Here's my config :
<http use-expressions="true" create-session="stateless">
<form-login login-page="/login"
login-processing-url="/static/j_spring_security_check"
authentication-failure-url="/login?login_error=t" />
<logout logout-url="/static/j_spring_security_logout"/>
<intercept-url pattern="/person/test/**"
access="isAuthenticated() and principal.username=='albertkam'"
/>
<intercept-url pattern="/person/**" access="hasRole('ROLE_NORMAL')"/>
<remember-me
key="spitterKey"
token-validity-seconds="2419200"/>
</http>
With create-session="stateless" :
accessing http://myhost:8080/mycontext/person/blah
goes to login page
returns to homepage url http://myhost:8080/mycontext after logging in (i expect it returns to the protected resource)
Without create-session="stateless", which defaults to ifRequired (stateful) :
accessing http://myhost:8080/mycontext/person/blah
goes to login page
returns to the protected url http://myhost:8080/mycontext/person/ blah after logging in (this is correct behaviour , but stateful)
You can use always-use-default-target="false" on <form-login>to prevent going to default page after successful login.

Resources