I have a requirement to get user claims of a user logged into API Manager. I would prefer to do this using jaggery.
However, when I try the following
var carbon = require('carbon');
var tenantId = -1234;
var url = 'https://10.100.0.49:9443/admin/services/';
var server = new carbon.server.Server(url);
var userManager = new carbon.user.UserManager(server, tenantId);
var user1 = new carbon.user.User(userManager, 'admin');
var userClaims = user1.getClaimsForSet(['http://wso2.org/claims/givenname'],'default');
print(userClaims);
I get {} as the response. I have added a value for givenname for admin through the management console
I have also tried to get the claim value for another user who signed up to the API Store but to no avail.
Apart from this, I created a js module within carbon.user, declared it in module.xml and called it through a jag file. Once again, I get a response but it's empty ie. {}. The service I linked through js was org.wso2.carbon.um.ws.service.UserStoreManagerService
I am actually using API Manager in conjunction with Identity Server. Both servers have been clustered according to the documentation given here
https://docs.wso2.com/display/CLUSTER44x/Configuring+the+Identity+Server+5.2.0+as+a+Key+Manager+with+API+Manager+2.0.0
and here
https://docs.wso2.com/display/CLUSTER44x/Configuring+the+Pre-Packaged+Identity+Server+5.2.0+with+API+Manager+2.0.0
Since the userstore is the same, I presume that even though the Identity Server is handling user management, I should be able to get the claims through API Manager.
However, just to be sure, I have also tried using API Manager as is and retrieving claims by the above method.
What could be the cause of this and how do I retrieve the claims I need?
Related
I am working on a Xamarin.Forms based crossplatform app targetting iOS and Android. My backend is an ASP.NET Webapplication hosted as an Azure App Service and users can register accounts that I manage with Azure Active Directory B2C. For authentication, I use MSAL 4.0 and the client application communicates with the backend using the MobileServiceClient library.
Because the users' data has relationships, I chose to let the controllers' put methods add the users' SIDs automatically and filter requested data on that SID, because this identifier is available after authorization though the users IClaimsPrincipal anyway.
However, I don't understand the origins of these SIDs because I cannot find them anywhere else.
This is what I can tell so far:
Within Azure ADB2C, I have two registered users. One of them (UserA) came in using Facebook as IdentityProvider, the other (UserB) Microsoft.
UserA has the Object Id FFC1*** on ADB2C.
UserB has the Object Id E990*** on ADB2C.
Both have the same name, but different registered email addresses.
This is how I instantiate the MSAL client:
public static IPublicClientApplication PCA = null;
...
PCA = PublicClientApplicationBuilder.Create(ClientID)
.WithRedirectUri($"msal{ClientID}://auth")
.WithB2CAuthority(Authority)
.WithIosKeychainSecurityGroup("com.microsoft.msalrocks")
.Build();
ClientId refers to Azure Active Directory B2C > Applications > Application > Application Id
Authority resolves to something like https://application.b2clogin.com/tfp/application.onmicrosoft.com/B2C_1_SignInSignUp
The policy configuration (user flow) on B2C is configured to include the following claims:
Given Name
Identity Provider
User's Object Id
I log in using MSAL this way:
var accounts = await App.PCA.GetAccountsAsync();
var result = await App.PCA.AcquireTokenSilent(
App.Scopes,
accounts.FirstOrDefault())
.WithB2CAuthority(App.Authority)
.ExecuteAsync();
App.Scopes resolves to
public static string[] Scopes = {
"https://application.onmicrosoft.com/api/user_impersonation",
"https://application.onmicrosoft.com/api/offline_access"};
At this point, I have an AuthenticationResult which I could extract valuable information from such as the users' given name or the Object Id which equals the Object Id I can also see in the user management pane in my Azure B2C directory:
JObject authenticatedUser = AuthenticationHelper.ParseIdToken(result.IdToken);
var objectId = authenticatedUser["sub"]?.ToString();
var username = authenticatedUser["given_name"]?.ToString();
The AuthenticationResult contains an IdToken and an AccessToken. They are almost identical with the AccessToken adding an scp attribute containing scopes. In my case it contains "user_impersonation".
Now with the user being authenticated against ADB2C, I need my app to also forward the authentication to ZUMO, that is, the MobileServiceClient, so that the user can make authorized calls against my backends' controllers.
For this, I need the resturned AccessToken (which I can also extract from the above AuthenticationResult), wrap it into a JObject and finally transmit it to the MobileServiceClient like this:
MobileServiceClient client;
client = new MobileServiceClient("https://application.azurewebsites.net");
var zumoPayload = new JObject()
{
["access_token"] = result.AccessToken
};
await client.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, zumoPayload);
Now that the MobileServiceClient has an authenticated user, every future httprequest will contain respective information that the controllers' [authorize] attribute satisfy.
HOWEVER.
This is when it becomes strange.
When the MobileServiceClient is instantiated and its LoginAsync method called using the ZumoPayload from above, the resulting MobileServiceUser is being populated with two properties:
MobileServiceAuthenticationToken and
UserId
The funny thing is, that this token looks very different from the IdToken or AccessToken I received when authenticating with MSAL, but what bugs me even more is that the User Id is even something totally different!
There is a sub attribute included containing something like sid:956b*** for UserA and sid:e358*** for UserB which clearly differ from the above Object Ids.
Can anyone explain to me where these SIDs come from?
Is there an example of how to authenticate azure resource using User Managed Identity using c#? I am using the following code to authenticate using system managed identity and it works fine. but not sure about how to pass the user managed identity resource in the following example.
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secret = await keyVaultClient.GetSecretAsync("https://mykeyvaultname.vault.azure.net/secrets/test")
.ConfigureAwait(false);
return new string[] { secret.Value };
Please see the documentation here. This feature is in the 1.2.0-preview version of the library. It only works on Azure VMs and VMSS as of now. You need to set the client id in a connection string, which can either be specified in the constructor or in the env variable (documentation of other connection string options here). In this scenario, the constructor is recommended, so you can use developer identity/ cert for local and switch to the user-assigned identity on Azure.
Update: The library has been updated to support user assigned identity in App Services as well as part of 1.2.0-preview2.
I am developing a small App to allow the user to store To-Do items. I am using Firebase ass my backend.
For the first iteration I don't want the user to have to sign-up, but still only see it's own data. My first thought was just to use the anonymous authentication, store the UID an reuse it everytime the app is started. This is not possible since the session is gonna time out at some point and the user would get a new UID the next time.
I of course want to make sure that a user can only see it's own items using the Firebase Security & Rules.
The idea would be to save the items like this: app.firebase.com/user/123456/todo-item
123456 beeing the unique ID of the user.
Can I create a unique identifier myself and still use the Firebase Security & Rules?
You would have to run your own custom authentication solution.
When the Activity loads, you'll have to make a request to your server. Then on the server you can create tokens for a user when they load the page:
// These payload properties are accessible
// by Security Rules which is awesome
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("uid", "uniqueId1");
payload.put("some", "arbitrary");
payload.put("data", "here");
TokenGenerator tokenGenerator = new TokenGenerator("<YOUR_FIREBASE_SECRET>");
String token = tokenGenerator.createToken(payload);
There's more packages than just Java, so read the docs.
Then when you deliver the token back to the user, you would need to store the token locally.
Once the token is stored, you can retrieve it and authenticate.
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");
ref.authWithCustomToken(AUTH_TOKEN, new Firebase.AuthResultHandler() {
#Override
public void onAuthenticationError(FirebaseError error) {
System.err.println("Login Failed! " + error.getMessage());
}
#Override
public void onAuthenticated(AuthData authData) {
// authenticated
}
});
You probably aren't thrilled about having to run a server, but take a look at using Google AppEngine with the Firebase JVM client. It's pretty easy and handles the server maintenance for you.
This tutorial by a former Google Cloud tools member, and current Firebase team member is a great place to start.
I'm working on a SaaS application built around ASP.net MVC & WebAPI and want to make it easy for enterprises to use my service. Example would be Office 365 Basic Authentication (Active Profile) where the user enters his username/password on microsoft's site (or desktop app) and he is authenticated against his employer's Active Directory. My understanding so far is that I would need to create a RP-STS which will accept credentials and then forward those to AD FS Proxy running on the client company's AD server. Is this correct?
If yes, then how do I implement this? Setting up AD server adding a Relying Party and AD FS Proxy Role is easy, so that's really not an issue. I just need to figure out how to create/setup RP-STS service and any other steps involved in this process. There just isn't an example/tutorial of this in .net
I believe this msdn blog post describes exactly what you're asking for. It has a complete walkthrough of the entire process, including creating an RP by creating a normal WCF service, and then use the provided utility to configure the service to trust your ADFS.
http://blogs.msdn.com/b/mcsuksoldev/archive/2011/08/17/federated-security-how-to-setup-and-call-a-wcf-service-secured-by-adfs-2-0.aspx
Edit:
This code, taken from the linked article (comments are mine), is a demonstration of active federation. The client application is manually retrieving a security token from the ADFS. Passive Federation would involve forwarding the user to a secure web page in which they could send their credentials directly to the ADFS. The major benefit of Passive Federation is that the end user's secret credentials are provided directly to the ADFS, and the RP's client side code never has access to it.
var requestTokenResponse = new RequestSecurityTokenResponse();
//The line below is the 'Active' federation
var token = Token.GetToken(#"mydomain\testuser", "p#ssw0rd", "http://services.testdomain.dev/wcfservice/Service.svc", out requestTokenResponse);
var wcfClient = new FederatedWCFClient<MyTestService.IService>(token, "WS2007FederationHttpBinding_IService"); // This must match the app.config
var client = wcfClient.Client as MyTestService.IService;
var result = client.GetData();
Console.WriteLine(result);
wcfClient.Close();
Take a look at these links:
https://github.com/OfficeDev/O365-WebApp-SingleTenant
https://github.com/OfficeDev/O365-WebApp-MultiTenant
It shows how to make an application using the office 365 api to authenticate and authorize the users.
Be aware about Single Tenant and Mult Tentant application, and choose the right one.
It's really easy to do that, I've done it couple months ago.
I found the answer on the blog: http://leandrob.com/2012/04/requesting-a-token-from-adfs-2-0-using-ws-trust-with-username-and-password/
What this code essentially does is that it directly authenticates with the tenant's ADFS endpoint and gets a token as well. That's what I was looking for.
var stsEndpoint = "https://[server]/adfs/services/trust/13/UsernameMixed";
var relayPartyUri = "https://localhost:8080/WebApp";
var factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(stsEndpoint));
factory.TrustVersion = TrustVersion.WSTrust13;
// Username and Password here...
factory.Credentials.UserName.UserName = user;
factory.Credentials.UserName.Password = password;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointAddress(relayPartyUri),
KeyType = KeyTypes.Bearer,
};
var channel = factory.CreateChannel();
SecurityToken token = channel.Issue(rst);
Another good article on that blog is: http://leandrob.com/2012/02/request-a-token-from-adfs-using-ws-trust-from-ios-objective-c-iphone-ipad-android-java-node-js-or-any-platform-or-language/ - which covers other similar scenarios.
I am writing a wrapper around a SOAP API. I have a service reference set up in VS2010 to point to the WSDL. When I make a call to login, the API returns a session variable in a cookie.
I've set allowCookies="true" on my binding in config.
I've implemented two API calls in my wrapper so far: login and logout.
I have a test harness that is a simple ASP.NET application that has a page for login and a page for logout.
When login is submitted:
using (var ApiClient = new ApiClient())
{
ApiClient.Login(txtUsername.Text, txtPassword.Text, txtOrganization.Text, txtIPAddress.Text);
}
And now in my ApiClient.Login method:
using (var soapService = new WSDLInterfaceClient())
{
var loginCredentials = new loginRequest
{
username = username,
password = password,
organization = organization
};
if (!string.IsNullOrWhiteSpace(ipAddress))
loginCredentials.ipAddress = ipAddress;
var loginResponse = soapService.Login(loginCredentials);
}
So this all goes off without a hitch. I was thinking I would need to remove the usings and have a class level WSDLInterfaceClient that I would use within my wrapper because I figured the cookies would be wiped out each time I constructed a new client. But that is simply not the case.
The logout method is implemented similarly. The logout API call will throw an exception if you try to logout without being logged in. Oddly enough, when I go to my logout page and submit (which in turn is constructing a new wrapper client and therefore a new service client) it recognizes that I am logged in. If I try to logout again it throws the exception as expected.
The cookies seem to be working in that even when constructing both a new interface client and a new wrapper client on each page, the cookies persist.
While this isn't a bad thing, I am perplexed as to how it is working. Is there somewhere that ASP.NET/WCF is saving these cookies for the session? How would this work in a console app?