Context
Our project has a collection of independent http services that work together we have
authentication service
service A
service B
service C
the purpose of A, B, & C is not important for this discussion. other than they interact with one another.
Authentication service is our implementation of Owin.Identity. Service A came online first and we (most likely) did not implement security integration correctly. We had to implement our own MachineKeyProtector to uprotect the identity and set the request context principal
var secureDataFormat = new TicketDataFormat(new MachineKeyProtector());
var ticket = secureDataFormat.Unprotect(accessToken);
request.GetRequestContext().Principal = new ClaimsPrincipal(ticket.Identity);
This already seems incorrect. I thought
//startup.cs
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
//web.config
//all our services share the same machine key
<machineKey decryptionKey="..." validationKey="..." validation="SHA1" decryption="AES" />
took care of security.
then comes the issue of automated tests. We are using Owin.Testing to mock HTTP calls and run integration tests. To get this to work, we need to create a JWT and we are currently using this code
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var protected = new MachineKeyProtector().Protect(ticket);
new TicketDataFormat(protected);
again using our MachineKeyProtector implementation. All of this is working but it doesn't seem right. I would have through Owin.Security.OAuth (or JWT?) would handle this for us.
We created MachineKeyProtector as a way to generate JWT tokens for our automated tests.
Questions/Problems
How can we generate a JWT without implementing our own MachineKeyProtector. I would assume there is a JwtTokenizer.Create(new Claims Identity()); call we could use to generate the authentication token, but I haven't been able to find it.
How do we configure security in service A, B, & C so the request principal is set without us setting it explicitly?
I tried to keep the context as simple as possible while providing some insight into where we currently are. If more information is need please ask.
Related
It's easy to create an ASP.NET MVC application that authenticates based on windows domain user. It's also easy to create one that uses individual accounts stored using Entity Framework. In fact, there are project templates for both.
But I want to utilize BOTH kinds of authentication in the same application. I tried to combine the code from both project templates. I have a problem in Startup.Auth.cs.
// from "Individual Accounts" template
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
The existence of cookie authentication owin middleware seems to cause domain identities to become un-authenticated. If I take this line out, the domain authentication works. But without it, I can't seem to support individual user accounts.
I've downloaded the katana project source code and examined CookieAuthenticationHandler.cs, but I don't quite understand how it works in the context of an OWIN pipeline.
How can I use the ASP.net identity framework to allow my application to authenticate users from the windows domain OR an application-specific user store?
The simplest approach is to have 2 different presentation Projects only for Authentication/Authorization.
This has the advantage of leaning on existing framework and standard configuration.
From there, you decide to either
create an AD user for every internet user, or
create a DB/Internet user for every AD user.
Creating an Identity user for each AD user is easier to implement further. Then the same cookies and filters can exist in the entire app.
In that case you can either
use subdomain(s) for your app
AD Authentiction Project can have the singular purpose of Authentication / Authorization, then the Web App can represent the rest of your app.
Alternatively, If you want a truly Unified Solution, use MohammadYounes/Owin-MixedAuth
MohammadYounes/Owin-MixedAuth
Install-Package OWIN-MixedAuth
In Web.config
<location path="MixedAuth">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
In in Startup.Auth.cs
app.UseMixedAuth(cookieOptions);
:
:
How it works:
The handler uses ApplyResponseChallengeAsync to confirm the request is a 401 challenge. If so, it redirects to the callback path to request authentication from IIS which is configured to query the AD.
AuthenticationResponseChallenge challenge = Helper.LookupChallenge(
Options.AuthenticationType, Options.AuthenticationMode);
A 401 challenge is caused by an unauthorized users attempting to use a resource that requires Authentication
The handler uses InvokeAsync to check if a request is coming from a callback path (IIS) and then calls AuthenticateCoreAsync
protected async override System.Threading.Tasks.Task<AuthenticationTicket>
AuthenticateCoreAsync()
{
AuthenticationProperties properties = UnpackStateParameter(Request.Query);
if (properties != null)
{
var logonUserIdentity = Options.Provider.GetLogonUserIdentity(Context);
if (logonUserIdentity.AuthenticationType != Options.CookieOptions.AuthenticationType
&& logonUserIdentity.IsAuthenticated)
{
AddCookieBackIfExists();
ClaimsIdentity claimsIdentity = new ClaimsIdentity(
logonUserIdentity.Claims, Options.SignInAsAuthenticationType);
// ExternalLoginInfo GetExternalLoginInfo(AuthenticateResult result)
claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier,
logonUserIdentity.User.Value, null, Options.AuthenticationType));
//could grab email from AD and add it to the claims list.
var ticket = new AuthenticationTicket(claimsIdentity, properties);
var context = new MixedAuthAuthenticatedContext(
Context,
claimsIdentity,
properties,
Options.AccessTokenFormat.Protect(ticket));
await Options.Provider.Authenticated(context);
return ticket;
}
}
return new AuthenticationTicket(null, properties);
}
AuthenticateCoreAsync uses AddCookieBackIfExists to read the claims cookie created by AD and creates it's own Claims based.
AD users are provided a Claims based Cookie identical to Web Users. AD is now like any other 3rd party authenticator (Google, FB, LinkedIN)
It's for this reason that I haven't been able to use pre-baked solutions for authentication. In our project, the passing years (and agile approach) have left us with 4 different ways to authenticate which is annoying, but we support all legacy versions of apps in the field so we have to preserve it all (at least for now).
I ended up creating a factory that figures out the authentication mechanism (through any of several means such as token format, presence of some other thing) and then returns a wrapper that carries the logic for validating that authentication method and setting the principal.
This gets kicked off in a custom HTTP module so that the principal is built and authenticated before the request gets to the controller. In your case, windows Auth would be the final fallback, I think. In our Web API application, we took the same approach but through a delegating handler instead of HTTP module. It's a type of local token federation, you could say. The current implementation allows us to add or modify any validation procedure, or add any other token format; in the end, the user ends up with a proper identity or gets denied. Only took a few days to implement.
It seems to me the best answer to this question is to use an authentication and authorization framework. There are plenty to choose from (both commercial and free). You could, of course, write your own but I would discourage it. Lots of very smart people get this wrong.
I would take a look at IdentityServer3. It's certainly not the only solution but its a pretty good authentication and authorization framework. It's open source and pretty easy to get up and running in a hurry. Your use case is a common one and you will find some very useful information at the link above. Clean separation between authorization and authentication, social authentication options, easy to work with json web tokens that encapsulate user claims, etc.
How it can help you
IdentityServer3 allows you to configure Identity Providers to handle authentication and there are plenty of extension points that will allow you to implement a chain of responsibility that can handle both of your scenarios. From the docs:
IdentityServer supports authentication using external identity providers. The external authentication mechanism must be encapsulated in a Katana authentication middleware.
Katana itself ships with middleware for Google, Facebook, Twitter, Microsoft Accounts, WS-Federation and OpenID Connect - but there are also community developed middlewares (including Yahoo, LinkedIn, and SAML2p).
To configure the middleware for the external providers, add a method to your project that accepts an IAppBuilder and a string as parameters.
IdentityServer3 supports AD as an identity providor via a browser login window and will support a more programmatic implementation via a custom grant. You can also take a look here for some more information on IdentityServer3 and AD authentication.
It will support windows authentication as well and you can take a look at here for information and examples on implementing that.
There is a pretty good getting started example here as well.
With the right configuration IdentityServer3 can handle your requirements. You will need to implement your own authentication providers and plug them into the framework but there isn't much more to it than that. As for authorization goes, there are plenty of options there as well.
In the scaffolding for an ASP.NET MVC project, the StartUp.Auth.cs file currently contains this code:
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Uncomment the following lines to enable logging in with third party login providers
app.UseMicrosoftAccountAuthentication(
clientId: "0000000000000000",
clientSecret: "xxxx-xxxxxxxxxxxxxxxxxxx-xxxxxxx");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
//app.UseGoogleAuthentication();
}
}
Uncommenting the app.UseXxxAuthentication() lines and adding in your provider's key and secret gives you the ability to use the respective providers to perform OAuth logins. Under the covers, these methods use classes derived from the Owin class AuthenticationMiddleware.
I have looked on the web, but I cannot find a custom implementation of AuthenticationMiddleware that links directly to a Windows Azure Active Directory instance. Are there any such implementations?
Is this the right way to use OAuth to connect to my Windows Azure Active Directory instance?
You should be able to go to your Package Manager, and NuGet import the Katana Owin implementations for Windows Azure AD, which will be listed as Microsoft.Owin.Security.ActiveDirectory This is the middleware that enables an application to use Microsoft's technology for authentication. The current version as of this post is 2.0.2
Once you have that, you should be able to leverage the middleware for AD and ADFS 2.1 oAuth tokens like so:
WindowsAzureActiveDirectoryBearerAuthenticationOptions myoptions = new WindowsAzureActiveDirectoryBearerAuthenticationOptions();
myoptions.Audience = "https://login.windows.net/myendpoint";
myoptions.Tenant = "mydirectory.onmicrosoft.com";
myoptions.AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive;
app.UseWindowsAzureActiveDirectoryBearerAuthentication(myoptions);
That should give you the ability to have the Owin middleware use Windows Azure AD Bearer Authentication in this scenario.
Happy coding!
I don't believe you can use WAAD in this way. Microsoft Account is for what used to be Windows Live ID (More information here), and this is different from WAAD. And the OAuth implementation in WAAD is not complete yet and in preview (more details here). The best way to use WAAD today is via WS-Federation / WIF.
The pain point in VS 2013 is that you can't do it easily manually, nor you can change the selected authentication once you created the project.
The easiest way to get the required configuration is to go and create new web app, and change the authentication. Chose Change Authentication at the very first step of the wizard (where you select the type of App - MVC, WebAPI, etc.). Then choose Organizational Account. It has only one option - Cloud single organization - enter your tenant domain name (may be the xxxx.onmicrosoft.com). And chose access level (Single Sign On, SSO + read directory data, SSO + read + write directory data). Next you will be asked to sign in with account which is Global Administrator in this Active Directory. The wizard will create necessary web.confg changes and Identity configuration.
There still no support in OWIN for WAAD, and it will create a new IdentityConfig.cs instead Startup.Auth.cs file. You can then copy generated files and web.config changes into your project. You can still combine WAAD with other providers and OWIN, but this still requires more advanced skills.
It is a little more complicated that it should be. But things may change for good in the future.
There is a new Owin middleware that adds Ws Federation authentication to your site with a few simple lines of code much like the individual account examples in the new MVC project template. It's currently in alpha but here is a link to an article explaining how to create your app in Windows Azure Active Directory and configure the OWIN middleware.
However this uses cookie authentication rather than OAuth tokens but this should be sufficient for a pure ASP MVC site.
I have a couple of applications (mobile and desktop) that I need a simple webservice created for authentication and to post information back to the clients.
After having man problems trying to figure out how to create a membership database or even find a previous one to check against with the WCF service I am using, I have stumbled upon service stack. So I have a couple of questions.
Does service stack have an out of the box database and provider so that I can simply add authentication for the clients, and have it create the database itself. So I do not have to create it from scratch.
Is their an example of a servicestack service and database already so I can use as a foundation?
The whole WCF services thing is having me confused. Basically all I am looking for is a service that I can use to authorize a mobile app and desktop app, and maybe later on add some extra functionality to it. It would need its own db since it won't be run from an existing website, and a way for me to manage them.
With WCF it seems overly complex for the task and I haven't found any examples with a database already to use and a way to manage them. Ideally I would of liked to have a blank website set up just so I could administer the accounts and have the WCF service use the same database.
Can this all be done easily with service stack, and could anyone point to an example for it already? If you have any tips on my current approach that would help aswell.
I recommend reading the Authentication and authorization wiki which explains the Authentication support built-into ServiceStack.
Backend Repository options
It describes all the potential backend repositories you can persist the authenticated UserData to, long-term:
OrmLite: OrmLiteAuthRepository in ServiceStack
Redis: RedisAuthRepository in ServiceStack
In Memory: InMemoryAuthRepository in ServiceStack
Mongo DB: MongoDBAuthRepository in ServiceStack.Authentication.MongoDB
Raven DB: RavenUserAuthRepository in ServiceStack.Authentication.RavenDB
NHibernate: NHibernateUserAuthRepository in ServiceStack.Authentication.NHibernate
Short-term Session / Caching providers
As well as all the different caching options that's used for fast, short-term data-access of authenticated client sessions:
In Memory: MemoryCacheClient in ServiceStack
Redis: RedisClient, PooledRedisClientManager or BasicRedisClientManager in ServiceStack.Redis
Memcached: MemcachedClientCache in ServiceStack.Caching.Memcached
Azure: AzureCacheClient in ServiceStack.Caching.Azure
By default the MemoryCacheClient is used if one isn't specified.
Example project
You can look at the source code for the SocialBootstrap API project which is deployed on http://bootstrapapi.apphb.com which is an example demo that showcases all of ServiceStack's supported authentication options enabled in a web application.
I'll re-post the code and documentation from the AppHost.ConfigureAuth(), since it already does a good job explaining how to configure it.
The AppSettings is used by most Auth Providers to access additional information stored the Web.Config:
var appSettings = new AppSettings();
You use the AuthFeature plugin to Register all Authentication methods you want to enable for this web app:
Plugins.Add(new AuthFeature(
() => new CustomUserSession(), //Use your own typed Custom UserSession type
new IAuthProvider[] {
new CredentialsAuthProvider(), //HTML Form post of UserName/Password credentials
new TwitterAuthProvider(appSettings), //Sign-in with Twitter
new FacebookAuthProvider(appSettings), //Sign-in with Facebook
new DigestAuthProvider(appSettings), //Sign-in with Digest Auth
new BasicAuthProvider(), //Sign-in with Basic Auth
new GoogleOpenIdOAuthProvider(appSettings), //Sign-in with Google OpenId
new YahooOpenIdOAuthProvider(appSettings), //Sign-in with Yahoo OpenId
new OpenIdOAuthProvider(appSettings), //Sign-in with Custom OpenId
}));
ServiceStack allows you to specify your own typed CustomUserSession which is what it will use to persist the UserAuth data into the Session.
If you want to enable Registration services for new users so they can register and login with their supplied credentials:
Plugins.Add(new RegistrationFeature());
You can optionally override the default registration validation with your own custom implementation:
//container.RegisterAs<CustomRegistrationValidator, IValidator<Registration>>();
If you are using an OrmLite RDBMS backend repository you need to register a DB Factory, in this case it's configured to access the UserAuth SQL Server DB:
var connStr = appSettings.Get("SQLSERVER_CONNECTION_STRING", //AppHarbor or Local connection string
ConfigUtils.GetConnectionString("UserAuth"));
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(connStr, //ConnectionString in Web.Config
SqlServerOrmLiteDialectProvider.Instance) {
ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
});
The above ConnectionFilter is optional, but allows you to profile the DB queries with ServiceStack's built-in Mini Profiler.
Now that you've registered your RDBMS connection above, you can hook it up so it becomes the IUserAuthRepository for the Authentication Feature:
//Use OrmLite DB Connection to persist the UserAuth and AuthProvider info
container.Register<IUserAuthRepository>(c =>
new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
If you use the OrmLiteAuthRepository, it can automatically create the backend User Auth tables required by the AuthFeature:
//Drop and re-create all Auth and registration tables
var authRepo = (OrmLiteAuthRepository)container.Resolve<IUserAuthRepository>();
if (appSettings.Get("RecreateAuthTables", false))
authRepo.DropAndReCreateTables();
else
authRepo.CreateMissingTables(); //Create only the missing tables
An existing web application I want to migrate to the Windows Azure Cloud authenticates users the following way somewhere in the (post)authenticaterequest event:
IPrincipal current = Thread.CurrentPrincipal;
if (current != null && ((IClaimsIdentity)current.Identity).Claims.Count > 0)
{
IPrincipal result = AuthManager.CreateGenericPrincipal(current.Identity);
HttpContext.Current.User = result;
Thread.CurrentPrincipal = result;
}
The CreateGenericPrincipal method looks up roles in a xml file for the claimsidentity and creates a new GenericPrincipal with that roles.
Pages that need authentication just perform
IPrincipal p = Thread.CurrentPrincipal;
p.IsInRole("rolesFromXml");
This works fine with one webrole instance since there is no big difference to normal IIS hosting. But will it still work with 2, 3 oder 5 instances? The Azure loadbalancer is not "sticky", users could be forwarded to another instance while using the application. Dunno if Thread.CurrentPrincipal is still the way to go.
I use claims-based identity here. The first time an user enters the page, he gets forwarded to a security token service. Until now, this only happens once. It would be annoying if that happens several times when using multiple instances..
Thanks!
What typically happens is that you are forwarded only once, the redirect dance (passive redirect) happens, and you get a token. The token is typically cached in a cookie in an encrypted format. So, subsequent requests do not do the redirect dance.
The challenge here is that since the cookie is encrypted, all servers in a web farm must have the encryption key to decrypt. Out of box, you will run into issues with WIF because it defaults to DPAPI. This type of encryption is intentionally different per machine. That breaks in the cloud.
What you need to do is upload a service certificate as part of your deployment and change the way the cookie encrypted to something that is webfarm friendly. Here is the magical code:
private void OnServiceConfigurationCreated(object sender,
ServiceConfigurationCreatedEventArgs e)
{
var sessionTransforms =
new List<CookieTransform>(
new CookieTransform[]
{
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform(
e.ServiceConfiguration.ServiceCertificate),
new RsaSignatureCookieTransform(
e.ServiceConfiguration.ServiceCertificate)
});
var sessionHandler = new
SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
sessionHandler);
}
This sets up your security token handler to use RSA Encryption with key material derived from the installed certificate.
There is more detail and information outlined here in this sample application that illustrates the problem and solution:
http://msdn.microsoft.com/en-us/library/ff966481.aspx
Additional Edit:
There is a pipeline in ASP.NET where WIF is configured. It hooks the authentication event and will pull the token from the cookie and build your IPrincipal so that subsequent code will have that in the context. You typically don't build the Principal yourself when using an STS. Instead, if you need to modify the Principal, you plugin to the pipeline in WIF and insert additional claims to the 'role' claim (actually a URI namespace). WIF will then use those claims to build the ClaimsPrincipal that will contain things like Roles and things just work (IsInRole, web.config auth, etc.).
If possible, it is best to have the token contain the roles as claims. This is a much longer discussion however around 'normalization' of claims to meaningful contexts. Remember, the claims you get from a IP-STS is in their own terms and they might not mean anything to your application. For example, I might get a claim from a customer that they are part of Adatum\Managers group. That is completely meaningless to my application, so what I would typically do is exchange that token for one that my app understands and in the process transform or normalize the claims by claim mappings (i.e. Adatum\Managers --> MyApplicationAdminRole). Windows Azure ACS service is very applicable here to help do that (normalize claims from different IPs).
I would recommend reading Vittorio's book on this all to get the common patterns here:
Eugenio's notes:
Adding to what #dunnry wrote, which is all correct. The proper extensibility point to augment your claim set in the Relying Party (your web app) is by using a ClaimsAuthenticationManager. The docs for this type are here. there are pointers to samples in that page. In that class you would read the roles from the XML file and add them to the ClaimsIdentity. The rest of the app would not worry about claims, etc. (especially if you are using roles like in your case). The RSA config for the cookies encryption solves the load balancer issue.
Look at my post, I just did the same thing.
http://therubblecoder.wordpress.com/2011/10/25/wif-and-load-balancing-with-mvc-3/
Basically the claims token needs to be available to any cluster node, so using a certificate on the sessiontokenhandler will prevent a specific node processing the token in a manner specific to an instance.
In the microsoft.identity element in the config, you need to have an element that looks like this.
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="****THUMBPRINT*****" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
The application pool will also need to get access to this otherwise it won't be able to find the certificate by thumbprint.
The above code will use this certicate when dealing with the token. If you don't have this setup you will get a null reference exception.
We have several websites that are set up in the following fashion:
Site1.Web - ASP.NET Web Project (.NET 4.0, WebForms)
Common.Core - Class Library Project (all db interaction)
The web project appears once for each site while the Common.Core project is shared among all sites. We have a login form in the web project that, in order to authenticate, calls into the class library. It would call off a code similar to below:
Common.Core.Authenticate auth = new Common.Core.Authenticate(conStr);
bool validLogin = auth.ValidateUser(userName, password);
if(validLogin)
{
Common.Core.User = auth.GetCurrentUser();
}
The higher ups are pushing for a middle layer service/app tier and want to use a more elegant solution to handle single sign on. Therefore, the decision has been made to use a WIF service to handle the login and validation. Furthermore, we want to try to minimize the code that has to change in each web project, i.e. try to keep as many changes as possible in Common.Core.
I have seen a few samples that show how to add an STS reference to a web project. This would work well in a scenario where the user validation isn't factored into another project like Core.Common. However, in our scenario, how could we handle validation while still going through the common class library?
Ideally, I would like to add an STS reference to the Core.Common class library and replace the direct db logic (auth.ValidateUser above) with a call to an STS service. However, is it even possible to do that? Does the request have to initiate in the web project? If so, is the STS reference required in both places?
Any tutorials or resources which follow the same web project -> class library -> STS service path would be greatly appreciated.
I would also recommend using WIF :-)
In a claims based scenario the authentication process is "reversed". Your app will not call anyone, it will receive the needed information from a trusted source (the STS).
The "STS Reference" is not a library reference. It's a logical connection between your app and the trusted source of security tokens. A token is the artifact your app will use to decide what to do with the user request.
I'd agree with #nzpcmad that it is likely you could entirely remove the calls to you Common.Core library. It might be useful to see what else can you do with it. What does the Common.Core.User object give you?
If it is just properties of a user (e.g. name, e-mail, roles, etc) it is very likely you could just create a new version that simply wraps the IPrincipal supplied byt WIF (a ClaimsPrincipal).
For example (approx. no error handling, pseudo-code):
public User CurrentUser()
{
var user = new User();
var cu = HttpContext.Current.User as IClaimsPrincipal;
user.Name = cu.Name;
user.eMail = (cu.Identity as IClaimsIdentity).Claims.First( c=> c.ClaimType = "eMail" ).Value;
return user;
}
As #nzpcmad says, you can use ADFS or some other STS. Your apps would not care.
One way to achieve this is to FedUtil the ASP.NET project with an instance of ADFS. Essentially, authentication is now "outsourced" and you can simply remove the call to the core library from your app. ADFS is then setup to return whatever attributes the program needs for authorisation as claims. You may need to transform these claims attributes to whatever attributes are passed back to the common core in subsequent calls.
Or you could make the common core "claims aware" in the sense that it now recognizes "claims attributes" as opposed to "common core" attributes. This involves using different .NET classes - no hookup to ADFS is required.
Word of warning - your authentication seems to be all DB related. ADFS cannot authenticate against a DB. It can only authenticate against an instance of AD in the domain that ADFS is installed in (or other AD if trust relationship between AD).
If you want to authenticate against a DB you need a custom STS which is then federated with ADFS. See here: Identity Server.