adfs 3.0 custom attribute store dynamic claim types - claims-based-identity

In our ADFS 3.0 we have a custom attribute-store that communicates with a rest-service to retrieve specific attributes based on the userid. These attributes comes with an urn and a value. My goal was to have the urn retrieved from the rest-service set to the claim-type but this type seems to be set in the so called template you create from the gui of ADFS. See below code:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
=> issue(store = "Custom_AttributeStore", types = ("my:custom:urn"), query = "dummyString", param = c.Value);
Is it possible with adfs claim rule language to set the claim types programmatically in my custom attributestore?

There is a way to dynamically emit any pair of claim type and value from a custom attribute store. This article helped me to figure it out.
Your custom attribute store needs to return a single column of string values, where each value represents a single claim type and its corresponding value, separated by a special character (a semicolon in this example):
public string[][] EndExecuteQuery(IAsyncResult result)
{
...
return new[]
{
new[] { "http://example/custom-type-1;Value 1" },
new[] { "http://example/custom-type-2;Value 2" },
...
};
}
Next, use a custom claim rule to retrieve values from your custom attribute store and create input claims of an arbitrary type from them. Use the add command (which creates input claims) instead of the issue command (which creates output claims).
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"] => add(store = "YourCustomAttributeStore", types = ("custom-type-value-pair"), query = "YourQuery", param = c.Value);
Finally, use another custom claim rule to pick up each of the input claims created in the previous step and use their values to issue the proper output claims. The RegexReplace function can be used to separate type and value.
c:[Type == "custom-type-value-pair"] => issue(Type = RegexReplace(c.Value, ";.*$", ""), Value = RegexReplace(c.Value, "^.*?;", ""));
It may be a little convoluted, but it works.

Related

HotChocolate: Dynamic schemas and how to update filters accordingly

NOTE: If you do know that the below is not possible, this information is just as valuable.
Im checking out HotChocolate and Ive looked into the dynamic schemas
I have taken the code in your Github-example This works ok. I have extended our Product-type like so:
//Same json as in your Github-sample, new properties are "color" and some more
foreach (var field in type.GetProperty("fields").EnumerateArray())
{
string name = field.GetString();
typeDefinition.Fields.Add(new ObjectFieldDefinition(field.GetString()!, type: TypeReference.Parse("String"), pureResolver: ctx =>
{
var product = ctx.Parent<Product>();
return product.SubTypeSpecific.ContainsKey(name) ? product.SubTypeSpecific[name] : null;
}));
}
now I have "moved out" dynamic properties from a Dictionary (That is a sub-object in my documentDb) to own properties. Works well.
BUT:
How can I extend my ProductFilter in the same fashion?
I would like to extend my current Product-filter so its possible to search on the new dynamic property "color"
getProducts(where : color : {eq :"blue" }}) {...}
I can create new FilterInputDefinition, but not extend existing filter (because there is no FilterInputTypeExtensions.CreateUnsafe()
If I manage to create the new filter, is there any way to update the IQueryable-generation so that the inputed color ("blue")
So the query to my CosmosDb will be created automatically?
Many thanks in advance.

Auth0 Get userId in response payload?

When a user logins using the Auth0 lock on my client side, I get an idToken, but also an idTokenPayload which looks like this:
idTokenPayload = {
audience: "AUTH0CLIENTID",
exp: 1494190538,
iat: 1494154538,
iss: "AUTH0DOMAIN"
sub: "USERNAME"
};
Would it be possible to return the userId in Auth0's database instead of the username in the sub field?
The reason I want to do this is that I want to keep Auth0's db for users, and I have on my server-side some Profile, Post, Comment etc entities which have a userId column. Right now before each request on my entities I need to populate the user by doing an extra request: let id = Profile.find("... where username === auth0.sub").getId(); (pseudo-code of course).
With the C# lock sdk, you get back an Auth0User after the call to the LoginAsync method in the Auth0 client. Let's call this variable auth0User. If I look at auth0User.Profile, a JObject (it's a JSON object if you're not using C#), it contains a JSON array named "identities". My identities variable initialization looks like:
var identities = (JArray)auth0User.Profile["identities"];
This array contains all the identity providers associated with the user. If like me you haven't attached any other sign in besides Auth0, there will be just 1 entry here. Each object in this JSON array will contain a "provider" string and a "user_id" string. If the provider says "auth0" then it's from Auth0. Since I don't use FB or other account types I'm not exactly sure what they say. Here's my C# code to get the UserID:
var identities = (JArray)auth0User.Profile["identities"];
if (identities != null)
{
foreach (var identity in identities)
{
var provider = (string)identity["provider"];
if (string.Equals(provider, "auth0"))
{
UserID = (string)identity["user_id"];
break;
}
}
}
I believe that this should all be provided standard without needing to add any rules or webhooks. This article should explain in more detail and also gives examples in javascript: auth0 normalized user profile

Cakephp Validation on API input data

I have an API that receives data in JSON, XML and FORM data. The API needs to do a bit of validation that depending on the data provided, depends on the data to be validated. I have a "sendmode" field that is required for each API call. If the sendmode = 1 then mobile,firstname and lastname are required fields, however, if sendmode is 2 then group is a required field.
My question is, how can I validate my data in my model according to data provided in the API call without having to do a bunch of If statements at the beginning of my controller?
Thanks
public function api_send() {
//Get Params
$data = $this->request->input('json_decode', TRUE);
//validate here -> first required
$data['sendmode'] //need to validate
$data['subject'] //need to validate
$data['message'] //need to validate
if($validate == false){
return;
break;
}
switch($data['sendmode']){
case 1:
$data['mobile'] //need to validate
$data['firstname'] //need to validate
$data['lastname'] //need to validate
if($validate == TRUE){
//save data
}
//etc
}
}
So I want all my validation done in my model, but first, I need to validate 3 fields, if thats true I need to continue, then if sendmode is 1, I need to validate other fields, as these fields will not exist if sendmode is 2 or 4 etc
First you pass that json (?) data to a model method. Inside your model have a method that switches the validation rules based on the type.
// Controller
$this->Model->validateApiCall($this->request->input('json_decode', TRUE));
// Model
public function setValidationRules($type = 'someDefault') {
switch($type){
case SendMode::GROUP_FIELDS:
$this->validate = array(/* your rules for that type here */);
// ...
}
public function validateApiCall($data) {
$this->setValidationRules($data['type']);
// return or do something else with the data depending on it if its validated or not
return $this->validate($data);
}
Oh, and if you really want to use integers for the types I would recommend to use constants like SendMode::GROUP_FIELDS. I usually create a tableless model for that. Constants are a lot better because if you do a typo it brings up a syntax error and while using plain integers nobody never ever is going to remember what the meaning of a random 3 or 4 or 1 is.

Modifying Error message at Client side. Custom Validation ASP .NET MVC

I am trying implement custom client side validation.It is a cross coupled validation. I have followed all steps and its working fine. But my requirement requires me to modify the ErrorMessage which is will be part of metadata(HTML 5 Data Attribute). The example is as follows
IClientValidatable implementation:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ValidationType = "salaryandloanconstraint";
rule.ValidationParameters.Add("loanconstraintvalue", _loanEligibleMultiplicity);
rule.ErrorMessage = "Salary Insufficient to sanction a loan amount of";
return new ModelClientValidationRule[] { rule };
}
The message which i have initilized to rule.ErrorMessage is incomplete. I want to append text which is taken from input field for LoanAmount property to the error message when the user enters.
In Summary is there any way which i can manipulate the error message(HTML5 DATA ATTRIBUTES) at the client side using JQuery?
check this url, may be this solve your issue:
$(".field-validation-error span", $("#form"))
.clone()
.appendTo("#error-summary")
.wrap("<li>");

Varying WCF Security Roles/Claims by Method Parameter

I have a class that implements IAuthorizationPolicy. I set up a custom Principal object based on the logged in user which has all of my base level roles (I have also done this using claims). Now I would like to change the roles that a particular principal has depending on a key value passed in as a message parameter.
The problem I am having is that the request message cannot be read in the authorization policy class because I don't have access to write the message back to the request context. I can copy and read the message in a ServiceAuthorizationManager derived class using an override of the CheckAccess method. However, I have to ensure that the GetAuthorizationPolicies method has already been called prior to doing that.
I am looking for suggestions on how I can vary the roles on a principal, based on whether or not the message contains a particular parameter. Basically, when the Evaluate method id called on the policy I want to do something like this:
string myObjectId = null;
if (!messageCopy.IsEmpty)
{
System.Xml.XmlDictionaryReader xdr = messageCopy.GetReaderAtBodyContents();
xdr.ReadToDecendant("objectId");
if (xdr.Read())
{
myObjectId = xdr.ReadContentAsString();
}
xdr.Close();
}
messageCopy.Close();
ClaimSet claims = (myObjectId != null) ?
MapClaims(identity, myObjectId) : MapClaims(identity);
DefaultPrincipal principal = new DefaultPrincipal(identity, claims);
After an entire day of attempted failures, I gave up on trying to read the message body and used an easier method, adding a SOAP message header. When calling the service I now perform the following:
using (new OperationContextScope((IContextChannel)myService)) {
OperationContext.Current.OutgoingMessageHeaders.Add(
MessageHeader.CreateHeader("objectId", "http://tempuri.org/", "object value"));
myService.BeginMyOperation(parm, callback, state);
}
Then in my service authorization policy's Evaluate method I do this:
int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(
"objectId", "http://tempuri.org/");
string myObjectId = (index < 0) ? null :
OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);
ClaimSet claims = (myObjectId != null) ?
MapClaims(identity, myObjectId) : MapClaims(identity);
DefaultPrincipal principal = new DefaultPrincipal(identity, claims);
I run into the same situation while developing WebAPI security and I choosen the next approach:
Method that recieves argument creates AuthorizationContext where it passes the argument as Resource claim
My custom ClaimsAuthorizationManager then can get argument from AuthorizationContext.Resource and use it from authorization.