ITfoxtec -SAML2 - read configuration values from a DB - itfoxtec-identity-saml2

We are using the ITfoxtec SAML2 library for Single Sign On with SAML2 authentication for some of our external Clients.
So far we only have one client that wants SSO, but we anticipate that we will get more clients that want to use SSO, so my question is that can we store the setting in a Database rather than read from a Configuration file.
We would like to look up the values for each client from a data store and then build the SAML2 Configuration and then do the binding.
var binding = new Saml2RedirectBinding();
binding.SetRelayStateQuery(new Dictionary<string, string> { { "RelayState", relayStateReturnUrl ?? Url.Content("~/") } });
//The bindingResult is a SAML2 redirectBinding - this create a browser redirect to the IDP.
var bindingResult = binding.Bind(new Saml2AuthnRequest(_samlConfig));
So we would build out the Saml2Configuration our selves (Or perhaps store those in a Database table and look it up based on the client.
The idea is to pass in a custom SAMLConfiguration rather than reading it from the App settings.
Would this approach work, would the ITfoxtec have a sample for this approach ?

Multible IdP and RP support is implemented in FoxIDs in the SamlConfigurationLogic.cs class. You can either implement you own version of the SAML config logic or user FoxIDs to handle the multible IdP connections for your application.
Related questions and answers:
ITfoxtec SAML 2.0: Dynamic configuration
Load SAML2 configuration on the runtime instead of loading it on the Startup

Related

Asp.Net Core Identity with multiple SAML IDPs using ITFoxTec.Identity.Saml2

Are there any examples of using itfoxtec-identity-saml2 with asp.net core Identity.
Specifically, I have many SAML Idps (https://stubidp.sustainsys.com, Okta, Auth0, Salesforce, etc) and I want to add them using AuthenticationBuilder.
public static class Saml2Extensions
{
public static AuthenticationBuilder AddSaml(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<Saml2Options> configureOptions)
{
...
}
}
A good example would have a mix in of Google, Azure both using OIDC, and a few SAML ones.
I'm afraid that I do not have sutch an example. I always put a proxy / broker IdP in between, in my case I use FoxIDs. That way the application only need to know about one IdP and would then ask the broker IdP to handle the up-stream IdP authentication.

Retrieving Emails from Office365 using OAuth2.0

I am looking for a complete Step-by-step to accomplish the following objective. I have been looking around and trying many, many ways, but not one of them works.
Objective: using C# .net core code (in Azure Functions) connect to a shared mailbox of Office 365 to retrieve emails [with date filter] to do some processing, then move that email from Inbox into another folder (Processed). I want to use MailKit (or something similar
that is free and has MIT license) to retrieve, load and parse the emails.
What I have done, but of course, I can be way off…
In Azure Active Directory, I have created an App Registration
In API Permissions, I have added and granted (I am an admin) a lot of permissions (everything I guess may be related to this, from
Email, to IMAP, SMTP, POP, Application, User and a bunch of other permissions.
In Certificates & Secrets, I created a client secret and recorded the secret (Value)
From Overview, I recorded the Client ID, Tenant ID, etc.
Code (I tried several variation of this…)
string[] scopes = {"https://graph.microsoft.com/.default" }
/*
for scopes, I have also tried:
“https://graph.microsoft.com/IMAP.AccessAsUser.All”
“https://outlook.office.com/IMAP.AccessAsUser.All”
*/
var authority = authority + tenant;
/*
for authority, I have also tried:
“https://login.microsoftonline.com/“
“https://login.microsoftonline.com/common”
“https://login.microsoftonline.com/oauth2”, etc…
*/
var client = ConfidentialClientApplicationBuilder
.Create(clientID)
.WithClientSecret(secret)
.WithAuthority(new Uri(authority))
.Build();
/* Fails every time! */
CancellationToken cancellationToken = default;
var authResult = await app.AcquireTokenForClient(scopes)
.ExecuteAsync(cancellationToken);
/* MailKit to retrieve emails… */
/*
any step-by-step code using MailKit to
accomplish the Objective would be much appreciated.
*/
Firstly, you should not use this method to get the access token.
var client = ConfidentialClientApplicationBuilder
.Create(clientID)
.WithClientSecret(secret)
.WithAuthority(new Uri(authority))
.Build();
This method is using client credential flow which is not supported to use IMAP.AccessAsUser.All delegated permission.
This method mentioned by jstedfast is using Interactive provider. The interactive flow is used by mobile applications (Xamarin and UWP) and desktops applications to call Microsoft Graph.
So if configuring "http://localhost" as a Public client (mobile & desktop) redirect URI for your application doesn't work, I don't think you could implement it in the C# .net core Azure Function app. Azure Function app doesn't support login interactively within it. You can only use it in a console app.
But there are 2 workarounds which allow you to get the user access token for Microsoft Graph.
Implement Username/password provider to generate the client and access token. But it is using ROPC flow which is not recommended by Microsoft. See details on Warning tip.
Configure additional Login Params in App service to get the access token to call Microsoft Graph. Please refer to CONFIGURING AN APP SERVICE TO GET AN ACCESS TOKEN FOR AAD GRAPH API. The key point is changing the additionaloginparams to the following [“response_type=code id_token”, “resource=https://graph.microsoft.com”]. Related official document here.

Is it possible to use a single client RedirectUri for multi-tenant application in IdentityServer 4?

I have an IdentityServer 4 setup using SaasKit to support multi-tenant URL paths. This allows me to access the single IS4 instance in a multi-tenant way like so:
https://localhost:5000/tenant/tenant1/.well-known/openid-configuration
The IS4 instance uses a single database for client/scope configuration rather than one per tenant. Only the users database is separated per tenant.
My issue is that a client only ever has one configuration and so has one RedirectUri and PostLogoutRedirectUri, and these values must be tenant specific URL paths otherwise the callback won't be handled in the context of a tenant in the client app.
So, I can specify in my client app's tenant-specific OpenIdConnectOptions new values for CallbackPath, SignedOutCallbackPath and RemoteSignOutPath, e.g. like this:
options.CallbackPath = $"/tenant/{tenant}{options.CallbackPath}";
but obviously this requires the relevant tenant fragment to be included in the client's config RedirectUri property otherwise IS4 will invalidate the redirect uri.
Whilst I could use dynamic clientIds from the client app, I'd prefer not to create a tenant-specific client config in IS4 for each tenant, and deal with the management issues. Likewise, I'd prefer not to add all possible tenant-specific redirect URIs to the single client's config.
Instead, is it possible to implement and register with IS4 some custom components that supports the following functionality, and if so which interfaces should I implement?
A parameterized redirect URI path so the following can be specified:
https://localhost:5000/tenant/{tenant}/signin-oidc
Resolving a parameterized URI path into a real path when redirection is required.
You can implement a custom redirect URI validator.
For that, you need to create a class that implements IRedirectUriValidator and then register it like this:
services
.AddIdentityServer(...)
.AddRedirectUriValidator<MyCustomUriValidator>();
This way you can set the redirect URI for the client in the database using some notation to specify the tenant-dependent part of the URI and then check it at runtime with the custom validator.
Beware of the dangers associated with dynamic redirect URIs.

Master SAML Processing URL

I am trying to create a client that uses SAML, but I am not sure what the Master SAML Processing URL field should be.
I read the documentation, but its still not clear to me.
SAML uses assertions in order to verify resource accesses. The service provider needs to declare a specific url for this assertion exchange. On the other hand, there's the url which the Service Provider uses to manage the Single Sign Out process. The Master SAML Processing URL of Keycloak just lets you specify the same endpoint for both processes (you can still configure them individually using the fine grain configuration).

Custom SignIn & SignUp on RESTlet + GAE/J?

I am currently working on a small project using RESTlet on Google App Engine/Java.
I was searching.. searching.. and couldn't find the exact or understandable solutions for my doubts.
My question is that How am I suppose to implement my own SignIn & SignUp module without using google's UserService or Spring Security??
Is there any actual sample code available??
I mean SignUp part is just a simple JDO insert & select module. let's just say I've done it.
How am I supposed to handle each user's request session and authentication??
I am thinking about using HTTPS on every request.
Any suggestions or help would be really appreciated!
Thanks in advance.
In Restlet, you have security support on both client and server sides. On client side, you can specify security hints using the ChallengeResponse entity. This feature is open and you can specify the authentication type you want. In the following code, I use an http basic authentication based on username / password:
ClientResource cr = new ClientResource(uri);
ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;
ChallengeResponse authentication = new ChallengeResponse(
scheme, "username", "password");
cr.setChallengeResponse(authentication);
Restlet will automatically build necessary headers in the corresponding request. You can note that Restlet supports a wide range of authentication types through its extensions. I know that some work is done at the moment to support OAuth v2 (see http://wiki.restlet.org/developers/172-restlet/257-restlet/310-restlet.html).
On the server side, you need to secure accesses at routing level using the ChallengeAuthenticator entity, as described below. This can be done within your Restlet application:
public Restlet createInboundRoot() {
Router router = new Router(getContext());
ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(),
ChallengeScheme.HTTP_BASIC, "realm");
guard.setVerifier(verifier);
guard.setEnroler(enroler);
guard.setNext(router);
return guard;
}
Like for client side, this support is generic and is based on two interfaces that need to be specified on the guard:
The verifier one to check if authentication is successful
The enroler one to fill roles for the authenticated user
You can notice that same security technologies need to be use on both sides...
If you want to manage authentication session for user, you need to implement it by yourself using cookies.
When authentication successes on server side, you can return a cookie containing a security token that allows you checking the user from your database (for example). Some code like below can implement that:
CookieSetting cookie = new CookieSetting(0,
SECURITY_COOKIE_NAME, securityToken);
Series<CookieSetting> cookieSettings = response.getCookieSettings();
cookieSettings.clear();
cookieSettings.add(cookie);
You can extend for example the SecretVerifier class of Restlet to add a test on security data received and add this code when receiving the security cookie.
On client side, you need to add hints for authentication the first time and then re send the security cookie following times, as described below:
ClientResource clientResource = (...)
(...)
Cookie securityCookie = new Cookie(0,
SECURITY_COOKIE_NAME, securityToken);
clientResource.getRequest().getCookies().clear();
clientResource.getRequest().getCookies().add(securityCookie);
Hope it will help you!
Thierry
If you are interested in re-using social accounts, you need to integrate with each one like facebook oauth
And/Or use the app engine authentication via OpenID
Both ways define an API to authenticate a client, you can use the UserService or manage your own state via cookies.

Resources