I'm using the latest C# SAML2 library (4.3.1), and have been able to use it successfully with Okta; however, when trying to integrate with another identity provider, I'm getting the following error:
ArgumentException: IDX13300: 'System.String' must be an absolute Uri, was: 'System.Uri'
It seems to be complaining about the saml:AuthnContextDeclRef attribute, which has the value:
ncid/secure/form/30min/uri
I'm not sure, but I think maybe this attribute is expected to be an absolute Uri by the library. The customer says this value comes from their contract and is the same for everyone, so it can't be changed. They have other applications successfully integrated (they mentioned some are using ComponentSpace). Is there any setting I can change or fix you can provide for this to work? I've looked through the available settings and nothing looks like it is relevant. The only thing I can think to do at this point is to try another SAML library.
UPDATE:
So I was able to track the issue down to the Declaration Reference attribute not being an absolute Uri. This validation is in the Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext class which represents a portion of the Saml2 token. I agree that the best solution would be to change the Declaration Reference to an absolute Uri, but since the customer says they can't or won't change the value, I needed a solution.
I was able to download the ITFoxtec.Identity.Saml2 source code and make a few tweaks so it uses a custom Saml2Serializer that overrides the ReadAuthenticationContext method and skips the part that sets the Declaration Reference on the Authentication Context. ITFoxtec doesn’t use this property… in fact, it has code that sets it to null if it has a value, so preventing the property from getting set in the first place shouldn’t cause any issues, and it allows the SAML token to be read without triggering the validation error.
It sounds correct that the AuthnContextDeclRef value should be an absolute Uri.
Her an example of how to set a AuthnContextClassRef value:
RequestedAuthnContext = new RequestedAuthnContext
{
Comparison = AuthnContextComparisonTypes.Minimum,
AuthnContextClassRef = new string[]
{
//"https://data.gov.dk/concept/core/nsis/loa/Low"
"https://data.gov.dk/concept/core/nsis/loa/Substantial",
//"https://data.gov.dk/concept/core/nsis/loa/High"
},
}
Related
I am having the following problem, and so far haven't been able to find an effective solution for it. I have the following code in my Swagger spec:
SomeRequest:
type: object
properties:
client_date_of_birth:
type: string
format: date
example: "2021-09-17"
required:
- client_date_of_birth
This of course works fine, but the problem is introduced when I try to use FluentValidation instead of this approach. My FluentValidation code looks like this:
.RuleFor(i => i.ClientDateOfBirth)
.NotEmpty().WithMessage("Client's Date of Birth is empty")
.InclusiveBetween(new LocalDate(1870, 01, 01), todayDate);
I wish to display the FluentValidation message instead of the generic one from Swagger, but so far I haven't found a good way to do this.
If I remove client_date_of_birth as a required field, I will also open up the API's contract to allow this field as a null value (which I want to deal with at API level, not FluentValidation level) and if I set it up as a string instead of a date, I will also be opening up the API's contract to potentially unwanted behavior. Is there a way to override this particular behavior of Swagger with the FluentValidation's implementation?
Just as a clarification: I know I will get the FluentValidation error message if I remove the client_date_of_birth as a required field in the Swagger spec. My question is more about: can I override Swagger's behavior with FluentValidation's? the reason I want to keep it in both places is so the rules of the API's contract are transparent and written in the spec itself, rather than obscure and hidden in the code, even if I will be eventually using said code.
I am trying to localize a hosted service in response to a runtime condition which is fed in a variable lang, which represents a 2-letter ISO code (such as 'en', 'es', ...).
I set the localization service in my Startup.cs like this:
services.AddLocalization(options => { options.ResourcesPath = "xresx"; });
In my controller I have the following code:
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(lang);
I know this works, because when I pass in lang='es' the following:
var check = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
returns the correct value check = 'es'.
But then the next statement:
var msg = Resources.TestMsg
picks up my the value from my English resource file Resource.resx instead of Resource.es.resx.
What am I doing wrong, and how can I make it work?
Thanks!
OK, so what ultimately worked for me was following exactly the steps in this guide: https://joonasw.net/view/aspnet-core-localization-deep-dive
This link is the only source I've found that worked for me, and it was better than Microsoft's own documentation (which omits potential pitfalls like not naming your Resource files a very certain way).
Let me summarize some points:
One needs to inject IStringLocalizer into their controller, eg:
IStringLocalizer<MyController> _localizer;
Then inside the controller you can localize your strings, eg:
_localizer["STRINGKEY"]
where STRINGKEY is a key from your resource file.
Make sure to name your resource files properly. This is very important and is not documented by Microsoft as far as I know! Cost me a lot of time until I stumbled over the web link I've referenced above.
I was naming my files like this:
Resource.resx, Resource.es.resx etc
and the localized wasn't finding the values, instead just returning the key itself.
Eg, _localizer["STRINGKEY]" would return "STRINGKEY" rather than the corresponding value in the resource file.
So you must name your files instead using your Controller's name, like this:
Controllers.MyController.resx, Controllers.MyController.es.resx
These are the main points to remember. Sadly, Microsoft documentation glosses over a lot of this stuff.
I am building a mobile app for android with Xamarin and I want to use paypal for the user to pay us. After the payment I want to sent the confirmation to our server to check that the payment is good and complet and made the modification relating to the purchased.
I used the Android SDK to create a Java Binding Library. I used the tutorial at: https://github.com/paypal/PayPal-Android-SDK/blob/master/docs/single_payment.md
PaymentConfirmation confirm =
data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
I turned it into C# as so:
PaymentConfirmation confirm =
data.GetParcelableExtra(PaymentActivity.ExtraResultConfirmation);
This give me an exception saying that there exist an explicit cast so I add it:
PaymentConfirmation confirm =
(PaymentConfirmation)data.GetParcelableExtra(PaymentActivity.ExtraResultConfirmation)
This gives the following exception: System.InvaliCastException: Cannot cast from source type to destination type.
I have tried all I could think of so I'm looking for help.
A functional partial project may be found here:
https://github.com/PhilSim22/PartialProject/tree/master
I am under a nondisclosure agreement so everything not related to the issue have been stripped out. sorry for the inconveniant.
I found the answer. I had to use a JAVA cast instead of a normal cast. here is my solution:
var confirmObj = data.GetParcelableExtra (PaymentActivity.ExtraResultConfirmation);
PaymentConfirmation confirm = Android.Runtime.Extensions.JavaCast<PaymentConfirmation> (confirmObj);
im you don't find the solution maybe the component parse.com can help you:
https://parse.com/tutorials/integrating-with-third-party-services
With any invalid cast exception, the first thing I would try would be to store the result you wish to cast into a temporary variable, and look at its type, either in Debug mode or through logging.
Therefore I would do something like this:
object temp = data.GetParcelableExtra(PaymentActivity.ExtraResultConfirmation);
Console.WriteLine(temp.GetType().FullName);
Console.WriteLine("Can Assign: {0}", typeof(PaymentConfirmation).IsAssignableFrom(temp.GetType()));
This way, you could see if the returned type matches the casted type PaymentConfirmation.
Can you share the full class name of the source and destination classes?
I have a class which is being serialized/deserialized which works fine on most machines, but doesn't work on others (I have not been able to discern the difference, though on the boxes that present an issue I see other issues which have hints of "security/permission" issue [specifically my app can create a folder, but then can't write files to it... weird, but not the main issue]).
The error I get is:
Unable to generate a temporary class (result=1).
error CS0200: Property or indexer 'Namespace.Object.ParentOrganizations' cannot be assigned to -- it is read only
The following is the property:
public List<long> ParentOrganizations
{
get
{
return m_OrganizationIDs;
}
internal set
{
m_OrganizationIDs = value;
}
}
And if I change the "set" to public it does work, but I want to know why I have to do this on only a few specific boxes... so I can help assess why this and the other weird issues are occurring. I figure fixing a single weird issue at a time in my app is more of a hassle (and likely wrong) versus finding and resolving a system configuration issue.
UPDATE: Giving localMachine\Everyone full permissions to the executing folder resolves this issue as well, but is not a good long-term solution.
Assuming you are using one of the Common serializers, you are facing the problem that the serializer self is simply not able to set the ParentOrganizations property because the internal access modifier limit the access to all callers that are not inside the same Assembly then the property is. This causes the serializer ( that is located in an other asseambly ) to throw this exception because he is not allowed to access the property.
I have a REST ServiceStack Route.Add declaration like this
Routes.Add<MyDTOObject>(/servicename/{property1fromDTO}); but I need to pass an additional String value that is not defined on MyDTOObject class declaration.
Is it possible to pass something like this Routes.Add<MyDTOObject>(/servicename/{property1fromDTO}/{additionalString}); and retrieve it on my OnGet(MyDTOObject request){...} method implementation?
Currently I'm only able to get values from request for attributes that are defined on the MyDTOObject class declaration as specified by the Annotation used for the Routes.Add.
On my Service code I have this:
public override object OnGet(MyDTOObject request){ ...
request.property1fromDTO //get value
...}
but I cannot do this:
request.additionalString //get the value
because Visual Studio doesn't recognizes it as a property of type MyDTOObject
Help will be appreciated since I'm fairly new to ServiceStack and RESTful services. Thanks!
Not exactly sure what you're trying to achieve but you can use a wildcard at the end to absorb multiple paths, e.g:
Routes.Add("/save/{Year}/{Week}/{DaysString*}");
Which will populate the known variables and leave the rest in DayString for you to parse manually. See this answer for more details.
You can ignore the additional path with the {ignore} keyword, e.g:
Routes.Add<MyDto>(/servicename/{property1fromDTO}/{ignore});
You also have full access to the request from inside a Service with base.Request, e.g:
base.Request.QueryString["param"];
base.Request.PathInfo
base.Request.RawUrl
*Note: it looks like you're using the old API (i.e. OnGet). I recommend inheriting from Service so you can use the New API as the Old API was removed in the next v4 of ServiceStack.*