I have an MVC application that connects to CRM via the SDK's OrganizationService. The user logs in via a form in the application using their username and password. The CRM organization uses claims-based authentication and is connected to an ADFS 2.0 server.
Whenever I try to authenticate a user via their username and password, the newly instantiated service reuses an earlier token it got from successfully connecting. This makes it possible for users to log back in with just the correct username - even with an invalid password. The connection I'm using is set to have an instanceMode of PerInstance and that doesn't appear to help either.
I feel like I'm missing something essential here. Do I have to do something to tell CRM to re-authenticate my users' credentials or do I have to do something to tell our STS server to invalidate the previously issued token?
Thanks.
Your MVC application should not connect to CRM with the credentials of its users. Instead you should use the credentials of the service account of your MVC application (i.e. the application pool identity).
Of course the service account must be a user of the CRM Organization and (in CRM) this user account should be allowed to impersonate other users.
When your MVC application needs to access CRM on behalf of a specific user, it creates/gets an OrganizationServiceProxy instance (which can be reused) and sets its CallerId property to the systemuserid of the impersonated user.
Related
Our OAuth client application is built with Spring (through JHipster). The OAuth provider only serves the authentication functionality, but not the authorization functionality. Ideally, we should only allow a small group of people to access our OAuth client application, but not all those users who can sign in to the OAuth provider.
A solution I can think of at this moment is to create a custom user role to control the access in the OAuth client application. That, however, only can be done after the user's first sign-in when the user account data is created in the application.
Any better solutions?
Ideally you would apply user access control before creating user account data is created in the application. You could do so by providing an application specific scope or claim in the token that is generated for your application (aka. Client). Upon receiving the token, the application would check for the required attribute in the token before allowing access.
Currently I have this setup:
At login, and in every subsequent request after login, a mobile application that I have built uses Basic Authentication to authenticate the user with a web service that serves the app with information it requests.
On every request the Authorization header is inspected, the password and username are extracted from the header, the password is hashed using a proprietary DLL (so the web service doesn't actually contain the hashing algorithm) and compared to the hashed password associated with the username that is stored in the database.
I have now been asked to include Azure AD SSO in the login options.
After reading much about the topic, this looks seems to me like the setup:
I'm curious about a few things:
Is this setup correct, more or less?
Does the app send the Identity Token to the web service? If so, how does the webservice validate that token?
Is it correct that the webservice can match the Azure Identity to the DB user using one of the claims in the Security Token?
Where do Access Token fit in this picture?
Thanks for the help!
(Side Note: I know that Basic Authentication is not the preferred way to go in the first scenario. This was a temporary decision till we developed the token handling code, it only works using HTTPS and this is an internal application - you wouldn't be able to activate the app unless you have a code we give you)
I have little experience in azure ad but I think we could talk about your case.
First, whatever id token and access token are both jwt token, so to your web service application, you need to use jwt decode library to decrypt the token and get claims it contains. Here we need to know the difference between id token and access token, and I think you'll know that for your web service application, if it's more likely to play the role of an api application, you need to use access token because this token also contains user information. Then you need to add code in your program to decode the token and check if it's a 'valid' token for the request.(Because you've used azure ad to achieve the login part, you don't need to use your custom login part.)
Next, the signing in feature provided by azure ad requires to use account and password in the tenant which azure ad belongs to, the user accounts may look like xx#xx.onmicrosoft.com, it doesn't required to keep sycn with the accounts in your database, so it's difficult and needless for you to compare the user name obtained from the decoded token with those in your database. Because when your web service received the token(id or access token), that means someone has passed the authentication from azure ad. The token contains user information including role, expired time etc. You need to check if the token has expired and if has the correct scope. (Let's see a common situation, microsoft provides many graph apis to call, when accessing these api, we need to provide access token in request head with matching scope, e.g. https://graph.microsoft.com/v1.0/me
requires a delegated api permission of User.Read)
To sum up here, if your web service just required the users in your database to sign in then can be access, id token and access token are both suitable for you because they both contains user name like 'xx#xx.onmicrosoft.com', what you need to do is decode the token and check if the token has expired and whether this user exists in your database(you may set up a mapping between them).
I'm looking to use an identity service such as Azure B2C, Auth0 or OKTA to secure my application.
After the user signs up for an account, I need to display a custom registration form in my application in order to complete the registration. This form requires a business process behind the scenes and therefore it can't be part of the Identity Service (IDS are quite limited to capturing static data).
How do I ensure the user has completed the registration form on my application, when they sign in?
I'm thinking of using a claim such as "RegistrationComplete" and setting this to False when the user signs up. After they've signed up I can update this claim to be True.
I can't find any information online about this scenario so I not entirely sure its standard best practice.
Disclaimer: I work at Okta
Okta does have some features which should allow this. You can pull properties from the user's profile in Okta and put those properties on tokens as claims when the user is authenticating. So the user profile holds the state you care about. Your app/service can then read this claim from the token to determine if the form should be shown. Once the form is complete, your backend service can use the Okta APIs to update this user profile state, and then send the user through the authorize flow again to get a new token with the updated claim (specifying to not prompt for re-authentication when going through the authorize flow again).
There is a restful provider feature in azure ad b2c. Using the Rest Apis from any service along with custom policies in b2c, we can get user input and save that user input to any database. The REST apis can be used to orchestrate any step.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-step-custom
Background Explanation
When it comes to Identity Server 4, I come to a road block when i think about the design of user management in the client applications.
At this point, I have Identity Server setup using ASP Identity User Accounts as its user store.
I've built the UI for adding users to the Identity Server User Store.
I've tested setting up a client which is an MVC application, and I'm at the point where i can successfully authenticate with Identity Server and receive the openid identity token in my client application.
Identity Server is providing my client application with authentication.
Now, i need to concentrate on authorization within my app. This is where i get stuck, I need to create users local to the application, where user privileges within the application are stored.
I will need to link / associate the user in Identity Server to the user in the client application.
One way to do this would be to store the sub in the identity token as a user claim in the client application database (Asp Identity). This way, when a user authenticates i can locate them in the local db, based on the sub in the token.
The sub would have to be the user's unique id in the identity server user store. This way, if the user's email is changed, we can still link the two user accounts.
The user accounts in the client application wouldn't require passwords or email addresses, it would be purely claims and roles that are used for authorization across the application, as well as any other application specific information.
Question
Communication between Identity Server and the client application must need to exist when creating users in the client application?
We need to associate the two accounts?
We need to ensure that the client user account being created also has an Identity Server user account to be successfully authenticated?
When in the process should these tasks be complete? Im looking for some guidance in the flow of the communication between the two applications?
EDIT
Is it feasible that there are no User Accounts in the client application at all?
By this i mean that all user claims for a user are stored in the User store of Identity Server.
When a client authenticates with the IDP it requests only the user claims that are specific to the client application.
Example user claims in the User Store :-
"clientA_role" : "administrator"
"clientB_role" : "user"
When Client Application A authenticates, it requests only the scope clientA_role
This feels bad!
Any suggestions?
If you have many client applications then the way I recommend to do the user management is:
User Management Service:
Create a separate service for users management that identityserver will use as user store and applications will use as user repository when user metadata is needed.
Also why would you do something like:
Example user claims in the User Store :-
"clientA_role" : "administrator"
"clientB_role" : "user"
why not
just "roles": "user"? and in your application you will protect your resources using Authorize[Role] annotation.
do not create different fields for different applications, think of it as general user management service, I am pretty sure that standardizing your identity management will make it easier and will gain you maintainability and flexibility.
IdentityServer service handles identity management:
might be a good idea to keep user store inside the same service providing authorization if you feel that your application does not have such deep users management needs.
again in this case, store standard claims and return the claims you need inside an id_token or access-token.
Update:
For a specific user that have different roles in different applications:
let us say we have the following:
1- User1 has user role in first app and admin role in second app, then
User1.Roles{"FirstAppUser","SecondAppAdmin"}
2- User2 has admin role in both apps, then:
User2.Roles{"FirstAppAdmin","SecondAppAdmin"}
In my requirement, i have users in the IS. And I need to log into other applications by entering his user name and password. then the application should call the service provider which is defined inside IS and check whether the person who is trying to log into the application is actually authenticated user, then user name, email and user permissions also should be sent to the application as the response from the service provider.
I'm using OAuth2. Using Is 5.1.0.
Can anyone please guide me how to implement this
Can I check it with rest client tool like postman also?