How to implement a MetadataProvider that reads from database - spring-security

I'm adding SSO support to a spring-based application using the spring-security-saml extension. The idea will be that an IDP can register to use SSO with my application by filling out a form in the UI, specifying their entityId, SSO authentication URL (for SP-initialized login), and public X.509 certificate. This seems to be a common workflow for SaaS applications with SSO support.
I haven't yet been able to find a clean way of implementing this with the spring saml extension, and am wondering if there is one. FilesystemMetadataProvider and HTTPMetadataProvider provide support for loading IDP metadata from an XML file or an HTTP GET, respectively, but I need to instead generate the IDP metadata from the above attributes that are stored in the database.
My current thinking is to use ResourceBackedMetadataProvider and use an implementation of Resource that fetches the metadata attributes from the database for each registered IDP. It would look something like:
class DatabaseBackedResource implements Resource {
MetadataDao metadataDao; // autowired
public InputStream getInputStream() throws ResourceException {
Collection<MetadataPojo> idpMetadata = metadataDao.getMetadata();
return convertMetadataPojosToInputStream(idpMetadata);
}
private InputStream convertMetadataPojosToInputStream(Collection<MetadataPojo> metadata) {
// somehow convert attributes to XMLObject
// then write XMLObject to input stream
// ...
}
// implementations of other methods
// ...
}
where MetadataPojo is simply a wrapper object of the above 3 attributes provided by an IDP. What I'm not sure about is how to generate a valid IDP metadata java object, given some attributes, using the spring saml extension. I see that AbstractMetadataProvider#unmarshallMetadata(InputStream) converts the metadata input stream into an XMLObject, but it is not clear to me how I will convert my collection of MetadataPojos into an XMLObject.
In short, is there a tool in the spring saml extension library to build an IDP metadata xml object given a list of string attributes? Or, taking a step back, is there a better way to implement a MetadataProvider that fetches the metadata information from a database instead of a file or url?
Update:
I implemented the above MetadataProvider implementation and Resource subclass and it's been working like a charm. To generate the IDP metadata documents I used various subclasses of AbstractSAMLObjectBuilder (i.e. EntityDescriptorBuilder, IDPSSODescriptorBuilder, KeyDescriptorBuilder, etc.) and that worked pretty cleanly. It would be nice if the Spring SAML library had an IDPMetadataGenerator class like the MetadataGenerator that exists for SP metadata.
If there was a cleaner way about this, I'd love to hear it.

Related

spring security: what's the best practice for include value in permission?

In spring security, or RBAC, the Authority is described as a string, such as "download-file" means user can download file. If I need to limit user maximum daily download times and assign different values to different user, means the Authority contains dynamic values, how can I do this in spring security?
As you are alluding to there is a difference between authorities (i.e. roles) and permissions. Authorities tend to broadly apply for an application and have no state while permissions tend to be on specific objects and contain state.
This seems more like a domain problem than a permissions problem. Putting the logic into security feels a bit like having a form that must contain a valid email and checking the email format in security. I'd consider moving the logic outside of the security code.
If you really want to do this with Spring Security, I'd use a custom Bean that performs the check:
#Component
public class Download {
public boolean isAlowedForUser(Authentication authentication) {
// ...
return result;
}
public boolean isAllowedForCurrentUser() {
return isAllowedForUser(SecurityContextHolder.getContext().getAuthentiation());
}
}
Then you can autowire the Bean into your code and check the permission by invoking the code. If you prefer, you can also integrate into Spring Security's method security to perform the checks. To enable it you need to specify #EnableGlobalMethodSecurity(prePostEnabled = true) at the top of one of your configuration classes. Then you can use something like this on a Spring managed Bean:
#PreAuthorize("#download.isAllowedForCurrentUser()")
public void downloadFile(String fileName) {
Please refer this link
Spring Boot : Custom Role - Permission Authorization using SpEL
You can add new permission , like "DOWNLOAD_FILE" and authenticate if the current user has that permission using -
#PreAuthorize("hasPermission('DOWNLOAD_FILE')")
You can also limit access for Roles as well
#PreAuthorize("hasRole('ADMIN') and hasPermission('DOWNLOAD_FILE')")

Spring Security Expression Baed Access Control with JwtAuthenticationToken

I'm working on an RESTful sevice that uses spring-boot-starter-oauth2-resource-server for security. It has some complex endpoint authorization requirements that involve decisions based not just on roles but on other claims in the JWT like location. So the HttpSecurity config's hasRole is not enough.
Is there a way to use values from the JwtAuthenticationToken with Sprng Security's expression baed access control and the HttpSecurity's access(String attribute) method? Or is there some other way to integrate different claims into endpoint authorization?
Any advice wuld be much appreciated
You have access to the Authentication object using SPEL,
so expressions like:
authentication.token.claims['preferred_username'] == ......
I have used it in methods:
e.g.
PreAuthorize("#createSupportQueryRequest.username == authentication.token.claims['preferred_username']")
public void createNewQuery(#RequestBody CreateSupportQueryRequest createSupportQueryRequest) {
But it should also work in .access method.
For more complicated stuff you can reference a bean class thats in your context in the expressions using the #.
e.g.
.access("#isPortfolioOwnerOrAdmin.check()")
This will call the check method on the IsPortfolioOwnerOrAdmin class.
Your bean class has access to the token via the SecurityConect and you can perform your complex verification logic there and return either true or false.

How to change Grails Spring Security Cookie Path

I've got two grails applications using spring security:
Core
Module (user and role tables mapping to Core db tables)
I want to have a single sign on functionality using "remember me". The problem is that the cookies are stored in different paths "/Core" and "/Module" which I'm guessing is the reason why it isn't working.
Does anyone know how to change the cookie path to be "/"?
Notes:
Do I need to make a change in Spring Security or the Tomcat server configuration (using intellij)
I want to avoid setting up a CAS server if possible
I'm looking into plugins as an alternative
Thanks any help would be greatly appreciated
When the remember-me filter creates the remember-me cookie, it sets the cookie path to the context path obtained from the request object (see related source code here). If you want to customize this behavior, you'll need to override the setCookie() and cancelCookie() methods of the remember-me service implementation your application uses (either TokenBasedRememberMeServices or PersistentTokenBasedRememberMeServices) in a subclass, and configure the RememberMeAuthenticationFilter to use your custom implementation.
Here's how I impltemented it.
create a new service with extends TokenBasedRememberMeServices
override setCookie and cancelCookie method to set cookie path.
Add cookiePath variable and add method to setCookepath()
Update resources.groovy
rememberMeServices(YourTokenBasedRememberMeServices) {
userDetailsService = ref("userDetailsService")
key = conf.rememberMe.key
cookieName = conf.rememberMe.cookieName
alwaysRemember = conf.rememberMe.alwaysRemember
tokenValiditySeconds = conf.rememberMe.tokenValiditySeconds
cookiePath = some config variable
}

read the Membership/Profile/Role provider's connection from external file other then web.config

In my MVC application I am reading the Membership/Profile/Role provider's connection string from web.config. In web.config I am writing this connection string at runtime.
Now the problem is, if I update the web.config at run time, then each time my application will get restarted, it will slow down my application.
So I want to read the Membership/Profile/Role provider's connection string from any external file, other then web.config. Because if that external file is updated at run time, will not cause the application restart .
So please suggest me the way to read the connection string for role provider from external file .
Thanks in Advance
Aayushi
Can I get the connection string for role provider from external file , but not from web.config
The SqlMembershipProvider relies on the web.config to retrieve connection string settings, and will throw an exception of the connection string is not provided via the ASP.NET configuration model.
That said, SqlMembershipProvider is not a sealed class. You could override its initialization behavior to achieve an effect similar to what you describe.
If you have a finite number of connection strings, as might be the case if you are trying to manage connection strings at different stages (e.g., dev, test, production, etc.), you might include all your connection strings in your web.config, each with its own name, and implement some runtime logic to switch between them in a custom provider.
public class CustomSqlMembershipProvider : SqlMembershipProvider
{
public override void Initialize(string name, NameValueCollection config)
{
string connStringName = // retrieve from wherever you please...
config["connectionStringName"] = connStringName;
base.Initialize(name, config);
}
}
The limitation of this approach is clear if you need to support arbitrarily many connection strings. Even so, you can still build a custom membership provider with behavior like the SqlMembershipProvider via inheritance if you override the Initialize method and sufficiently replace its internal behavior.
Good luck.

OData - Data Service Simple Authentication

I would like to add simple authentication to Data Services, for now only to restrict access for particular applications by simple token.
I don't need Domain Authentication or Forms authentication.
I read a lot about authentication here:
http://franssenden.wordpress.com/2010/06/14/custom-security-odata-service-wcf-data-services/
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/03/10482.aspx
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/01/15/10119.aspx
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/01/10/10100.aspx
Unfortunately it all demands a loooot of work.
Most of all creating custom IHttpModule.
There should be more simple solution.
I know that when I create object context on the client (WPF) I can add Credentials.
Uri uri = new Uri("http://localhost/myapp/odata.svc");
MyEntities ent= new MyEntities (uri);
ent.Credentials = new NetworkCredential("token", "zx5as9vxc5sa9h0vb6523cv56");
But where can I read them (without implementation of custom IHttpModule)?
I thought that I can use something in class that is implementation of Data Service for example:
protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
string cred = args.OperationContext.AbsoluteRequestUri.UserInfo;
}
I'm not familiar with UserInfo but description for it stands "Gets the user name, password, ...)
So I have two main questions:
Where can I read Credentials included by typing ent.Credentials = new NetworkCredential("token", "zx5as9vxc5sa9h0vb6523cv56");
Where can I (if I can) set UserInfo on the client app and use it in OnStartProcessingRequest method.
Regards,
Daniel SkowroĊ„ski
There's a series of post about authentication and WCF Data Services (which is the .NET implementation of the OData protocol): http://blogs.msdn.com/b/astoriateam/archive/tags/authentication/
You should be able to find lot more information there (including code samples).

Resources