Azure UserDelegation Key Exception - azure

I am trying to generate UserDelegationKey for my Azure Storage Blob but i am getting an exception:
Can not instantiate Stax reader for XML source type class org.codehaus.stax2.io.Stax2ByteArraySource (unrecognized type)
This Exception occurs when i call getUserDelegationKey on BlobContainerAsyncClient
Version of my azure-storage-blob library is 12.12.0
Below is the code snippet
private void uploadNextWeekReportToAzure() {
BlobServiceAsyncClient blobServiceAsyncClient = blobServiceClientBuilder
.credential(new DefaultAzureCredentialBuilder().build())
.buildAsyncClient();
BlobContainerAsyncClient blobContainerAsyncClient = blobServiceAsyncClient.getBlobContainerAsyncClient("container name");
BlobAsyncClient blobAsyncClient = blobContainerAsyncClient.getBlobAsyncClient("blob name");
OffsetDateTime keyStart = OffsetDateTime.now();
OffsetDateTime keyExpiry = OffsetDateTime.now().plusDays(7);
blobServiceAsyncClient.getUserDelegationKey(keyStart,keyExpiry)
.doOnError(throwable -> log.error("Exception occurred:{}",throwable.getMessage()))
.doOnSuccess(userDelegationKey -> {
log.info("UserDelegationKey:{}",userDelegationKey.getValue());
String saSToken = generateSaSToken(blobAsyncClient, userDelegationKey);
log.info("SAS TOKEN:{}",saSToken);
})
.subscribe();
}
private String generateSaSToken(BlobAsyncClient blobAsyncClient,
UserDelegationKey userDelegationKey) {
BlobContainerSasPermission blobContainerSasPermission = new BlobContainerSasPermission()
.setReadPermission(true);
BlobServiceSasSignatureValues builder = new BlobServiceSasSignatureValues(
OffsetDateTime.now().plusDays(1), blobContainerSasPermission)
.setProtocol(SasProtocol.HTTPS_ONLY);
return String
.format("https://%s.blob.core.windows.net/%s/%s?%s", blobAsyncClient.getAccountName(),
blobAsyncClient.getContainerName(),
blobAsyncClient.getBlobName(),
blobAsyncClient.generateUserDelegationSas(builder, userDelegationKey));
}
Complete Exception Trace:
CallbackNotImplemented: java.lang.IllegalArgumentException: Can not instantiate Stax reader for XML source type class org.codehaus.stax2.io.Stax2ByteArraySource (unrecognized type)
Caused by: java.lang.IllegalArgumentException: Can not instantiate Stax reader for XML source type class org.codehaus.stax2.io.Stax2ByteArraySource (unrecognized type)
at io.strati.libs.forklift.com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:770)
at io.strati.libs.forklift.com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:345)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:631)
at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:29)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1124)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3643)
at com.azure.core.util.serializer.JacksonAdapter.deserialize(JacksonAdapter.java:281)
at com.azure.core.implementation.serializer.HttpResponseBodyDecoder.deserializeBody(HttpResponseBodyDecoder.java:169)
at com.azure.core.implementation.serializer.HttpResponseBodyDecoder.lambda$decodeByteArray$1(HttpResponseBodyDecoder.java:105)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2397)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110)
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoCacheTime.subscribeOrReturn(MonoCacheTime.java:143)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:173)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
at reactor.core.publisher.FluxDelaySubscription$DelaySubscriptionMainSubscriber.onNext(FluxDelaySubscription.java:188)
at reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
at reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.onNext(FluxTimeout.java:179)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:284)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
at reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
at reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.onNext(FluxRetryWhen.java:173)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
at reactor.core.publisher.Operators$MonoInnerProducerBase.complete(Operators.java:2663)
at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:180)
at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onComplete(MonoFlatMapMany.java:260)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:150)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:150)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159)
at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onComplete(FluxDoFinally.java:145)
at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:212)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:269)
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:401)
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:416)
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:470)
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:685)
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94)

Try this code to generate user delegation key and SAS
String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net", "accountName");,
blobServiceClient = new BlobServiceClientBuilder().endpoint(endpoint).credential(new DefaultAzureCredentialBuilder().build()).buildClient();
keyStart = OffsetDateTime.now();
keyExpiry = OffsetDateTime.now().plusDays(7);
userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart, keyExpiry);
BlobContainerSasPermission blobContainerSas = new BlobContainerSasPermission();
blobContainerSas.setReadPermission(true);
BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(keyExpiry,blobContainerSas);
BlobContainerClient blobContainerClient=blobServiceClient.getBlobContainerClient("containerName");
if (!blobContainerClient.exists())
blobContainerClient.create();
String sas = blobContainerClient.generateUserDelegationSas(blobServiceSasSignatureValues, userDelegationKey);
For more information refer this link
You may also check this method to Generate Key
The Get User Delegation Key operation gets a key that can be used to sign a user delegation SAS (shared access signature). A user delegation SAS grants access to resources in the Blob service using Azure Active Directory (Azure AD) credentials.
For more information refer this link

Related

Kusto data ingestion from an Azure Function App ends with a 403

I try to ingest data from azure function app into a ADX database. I followed the instruction found in the the article here.
The difference is, I'd like to insert data into the table. I struggle with a 403 error "Principal 'aadapp=;' is not authorized to access table"
What I did:
I have created a AAD App with the following API permissions:
AAD App configured permission
I configured the database via Kusto Explorer:
.add database myDB ingestors ('aadapp=;')
'theAADAppname'
.add table PressureRecords ingestors ('aadapp=;') 'theAADAppname'
.add table TemperatureRecords ingestors ('aadapp=;') 'theAADAppname'
My code:
var kcsbDM = new KustoConnectionStringBuilder($"https://ingest-{serviceNameAndRegion}.kusto.windows.net:443/").WithAadApplicationKeyAuthentication(
applicationClientId: "<my AD app Id>",
applicationKey: "<my App Secret from Certificates & secrets>",
authority: "<my tenant Id>");
using (var ingestClient = KustoIngestFactory.CreateQueuedIngestClient(kcsbDM))
{
var ingestProps = new KustoQueuedIngestionProperties(databaseName, tableName);
ingestProps.ReportLevel = IngestionReportLevel.FailuresAndSuccesses;
ingestProps.ReportMethod = IngestionReportMethod.Queue;
ingestProps.JSONMappingReference = mappingName;
ingestProps.Format = DataSourceFormat.json;
using (var memStream = new MemoryStream())
using (var writer = new StreamWriter(memStream))
{
var messageString = JsonConvert.SerializeObject(myObject); // maps to the table / mapping
writer.WriteLine(messageString);
writer.Flush();
memStream.Seek(0, SeekOrigin.Begin);
// Post ingestion message
ingestClient.IngestFromStream(memStream, ingestProps, leaveOpen: true);
}
The issue is that the mapping you are using in this ingestion command does not match the existing table schema (it has additional columns). In these cases Azure Data Explorer (Kusto) attempts to add the additional columns it finds in the mappings. Since the permission that the app has is 'ingestor', it cannot modify the table structure and thus the ingestion fails.
In your specific case, your table has a column that is written in a specific casing and in the ingestion mapping the same column has a different casing (for one character) so it is treated as a new column.
We will look into providing a better error message in this case.
Update: the issue is fixed in the system and now it works as expected.
Avnera thanks for your hint, potential it is an issue because of the Real vs double translation. In one of my first try I used double in the table and that worked. That is not longer possible, looks the supported data types changed.
My current configuration:
.create table PressureRecords ( Timestamp:datetime, DeviceId:guid, Pressure:real )
.create-or-alter table PressureRecords ingestion json mapping "PressureRecords"
'['
'{"column":"TimeStamp","path":"$.DateTime","datatype":"datetime","transform":null},'
'{"column":"DeviceId","path":"$.DeviceId","datatype":"guid","transform":null},'
'{"column":"Pressure","path":"$.Pressure","datatype":"real","transform":null}'
']'
public class PressureRecord
{
[JsonProperty(PropertyName = "Pressure")]
public double Pressure { get; set; }
[JsonProperty(PropertyName = "DateTime")]
public DateTime DateTime { get; set; } = DateTime.Now;
[JsonProperty(PropertyName = "DeviceId")]
[Key]
public Guid DeviceId { get; set; }
}

SQL Server Column Encryption using Azure Key Vault and Spring Boot

I need to save the data in SQL server having column encryption using the Azure Key vault
#Bean
#Primary
public DataSource dataSource() throws SQLException {
KeyVaultClient client = new KeyVaultClient(keyVaultCredentialService);
String userName = client.getSecret(vaultURL, "spring-datasource-username").value();
String password = client.getSecret(vaultURL, "spring-datasource-password").value();
String url = "jdbc:sqlserver://test.database.windows.net;databaseName=encryption_demo;columnEncryptionSetting=Enabled;";
String driverClass = client.getSecret(vaultURL, "spring-datasource-driverClassName").value();
DataSource dataSource = DataSourceBuilder
.create()
.username(userName)
.password(password)
.url(url)
.driverClassName(driverClass)
.build();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientId, clientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider); SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
return dataSource;
}
application.properties
azure.keyvault.uri= ....
azure.keyvault.client-id= ...
azure.keyvault.client-key= ...
SQLServer table
CREATE TABLE [dbo].[Patients](
[id] [int] PRIMARY KEY NOT NULL,
[ssn] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[first_name] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL,
[last_name] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL
)
GO
While saving the data in DB getting the error:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Internal error while encryption: Illegal key size
Download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Be sure to read the Readme included in the zip file for installation instructions and relevant details on possible export/import issues.
If using the mssql-jdbc-X.X.X.jre7.jar or sqljdbc41.jar, the policy files can be downloaded from Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download.
If using the mssql-jdbc-X.X.X.jre8.jar or sqljdbc42.jar, the policy files can be downloaded from Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download.
If using the mssql-jdbc-X.X.X.jre9.jar, no policy file needs to be downloaded. The jurisdiction policy in Java 9 defaults to unlimited strength encryption.
For more details, you could refer to this article.

Settings must be of the form "name=value" in Eventhub client creation

An exception of type 'System.FormatException' occurred in Microsoft.WindowsAzure.Storage.dll but was not handled in user code
Additional information: Settings must be of the form "name=value".
while creating eventProcessorHost in EventHub
var eventProcessorHost = new EventProcessorHost(
EhEntityPath,
EventHubConsumerGroup.DefaultGroupName,
EhConnectionString,
StorageConnectionString,
StorageContainerName);
Sample values
string EhConnectionString = "Endpoint=sb://namespacename-ns.servicebus.windows.net/;SharedAccessKeyName=receivepolicy;SharedAccessKey=v7IHIH+jB3+H2UMxEOr9kHYfhwj1Q=;EntityPath=sampleeventhub";
string EhEntityPath = "sampleeventhub";
string StorageContainerName = "containername"; //I have created in blob and type as container
string StorageAccountName = "storegenameinazure";
string StorageAccountKey = "GHasmRRJgI5s123ziDlfOKQ7IBrO23EvHpk++TV0L2hU2erdI7PyY+gtvUop67lIU0+zQsM09sQ==";
static readonly string StorageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", StorageAccountName, StorageAccountKey);
According to your description, I leverage Microsoft.Azure.ServiceBus.EventProcessorHost version (2.2.10) to test this issue.
An exception of type 'System.FormatException' occurred in Microsoft.WindowsAzure.Storage.dll but was not handled in user code. Additional information: Settings must be of the form "name=value".
Based on your code, I assumed that you have not built your EventProcessorHost constructor correctly, the constructor you used looks like this:
At this point, the parameter StorageContainerName you passed would be treated as storageConnectionString parameter, then you got the above error.
In summary, please build your EventProcessorHost with the correct constructor. Here are some tutorials you could refer to them (event-processor-host-best-practices and azure-event-hubs-processing).

Unable to parse the saml service provider metadata

I have metadata provided by service provider.
I am using System.IdentityModel.Metadata; namespace to parse this metadata.
Below is piece of code to parse metadata.
using (XmlReader reader = XmlReader.Create(new StringReader(metadata)))
{
System.IdentityModel.Metadata.MetadataSerializer ser = new System.IdentityModel.Metadata.MetadataSerializer();
var metadataObject = ser.ReadMetadata(reader);
var samlMetadata = ((EntityDescriptor)metadataObject);
entityIdTextBox.Text = samlMetadata.EntityId.Id;
}
I am unable to parse this metadata and getting below error message.
ID3276: The signing credentials cannot be resolved because signed XML does not contain a SecurityKeyIdentifier.
Below is service provider metadata.
<md:EntityDescriptor ID="V.phzM5jUbn3C.zk3RrwXxXaQiH" cacheDuration="PT1440M" entityID="https://PF-DEMO1" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#V.phzM5jUbn3C.zk3RrwXxXaQiH"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>45KpBmol54EyK76KTKqFPMp4aDzzSVCLAu7CZ7SYq8A=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>CmHeuxi5PXdKpVoz3EiWIMa2VyUA49A6GdxokjyEk9Ma2UlWTMD9QM3lExwgtGIhPpjxOJxG2ynF7lFxyp6CvI4DaCsC787K9oo32gth9fCiKJrqgFeX0JSeRjjmZvkwbg+yuj2CMZ+0bAUQNE5cv+QlESetySARQjtx+GUXmAA=</ds:SignatureValue></ds:Signature><md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIB8TCCAVqgAwIBAgIGATDbjNSDMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9RdWljayBTdGFydCBBcHAxEjAQBgNVBAMTCWxvY2FsaG9zdDAgFw0xMTA2MjkxMzE4MTdaGA8yMTExMDYwNTEzMTgxN1owOzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1F1aWNrIFN0YXJ0IEFwcDESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCtsj/v026YKYT/VPBdcK3tfxVdGZ0caA0kmwyr9+5yTVxp4rVGnkgKP+WL5YVaOJU+Wcj75yNvvEYx4/Vgtxhf0NLiGp1pWaEuRrC2aPrmx/0vt/0gdHLaUXq7Jj0cOhSgq+SM/wjKqT/+cED932UblZht3jFOuQvf3bTqosr8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAF9Y0gznNwteCSn8cpgepzgYEgyrZtLJNc2eI5aEl9CwiyV+6oOeXVm1jZjcT9eOfusnJjHzr1AQdHMcDSSRAsevqYnDC9bpvb1SAZJq8HHHFJ7WTQtLLscDGpyPbopOJ2fJUWxkJcjUjmUIJuSwYGKj1l9wkbF1tK2xqjJDPOUR</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://10.164.43.248:9031/sp/SLO.saml2"/><md:AssertionConsumerService index="0" Location="https://10.164.43.248:9031/sp/ACS.saml2" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" isDefault="true"/><md:AttributeConsumingService index="0"><md:ServiceName xml:lang="en">AttributeContract</md:ServiceName><md:RequestedAttribute Name="http://schemas.xmlsoap.org/claims/UPN"/><md:RequestedAttribute Name="http://schemas.auth360.net/2012/01/requestcontext/claims/x-am-mail"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/claims/Group"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"/><md:RequestedAttribute Name="memberOf"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/uid"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/claims/EmailAddress"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid"/><md:RequestedAttribute Name="http://schemas.efactum.net/ws/2008/identity/claims/fid"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid"/><md:RequestedAttribute Name="http://schemas.auth360.net/2012/01/requestcontext/claims/x-am-uid"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/claims/CommonName"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier"/><md:RequestedAttribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod"/><md:RequestedAttribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"/><md:RequestedAttribute Name="http://schemas.efactum.net/claims/role"/><md:RequestedAttribute Name="http://schemas.efactum.net/claims/emailaddress"/></md:AttributeConsumingService></md:SPSSODescriptor><md:ContactPerson contactType="administrative"/></md:EntityDescriptor>
Please advise for same.

Single Sign On With ACS through Multiple Applications

Simple Single Sign-On question
I Have two MVC4 applications:
**1**- http://localhost/BikeShop
ACS Relying Party:
- Name: **BikeShop**
- Return Url: **http://localhost/BikeShop**
- Token Format: **SAML 2.0**
**2**- http://localhost/BikePartsShop
ACS Relying Party:
- Name: **BikePartsShop**
- Return Url: **http://localhost/BikePartsShop**
- Token Format: **SAML 2.0**
The Scenario I have
I access BikeShop and the ACS Login Page is presented and I choose my Identity.
I now can do stuff on BikeShop.
Then I access BikePartsShop and the ACS Login Page is presented and I can choose my Identity.
The Scenario I must have
I access BikeShop and the ACS Login Page is presented and I choose my Identity.
I now can do stuff on BikeShop.
Then I access BikePartsShop and the ACS authorizes the same Identity
used in the BikeShop without further user intervention.
Has anyone implemented this scenario?
Best Regards, and thank you!
You can use the ACS management service to configure multiple reply addresses for the same relying party. See this link for details on how to add an RP. From the linked code sample, register more addresses as follows:
RelyingParty relyingParty = new RelyingParty()
{
Name = "BikeShop",
AsymmetricTokenEncryptionRequired = false,
TokenType = "SAML_2_0",
TokenLifetime = 3600
};
svc.AddToRelyingParties(relyingParty);
RelyingPartyAddress realm = new RelyingPartyAddress()
{
Address = "http://localhost/",
EndpointType = "Realm"
};
RelyingPartyAddress replyAddress1 = new RelyingPartyAddress()
{
Address = "http://localhost/BikeShop",
EndpointType = "Reply"
};
RelyingPartyAddress replyAddress2 = new RelyingPartyAddress()
{
Address = "http://localhost/BikePartsShop",
EndpointType = "Reply"
};
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", realmAddress);
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress1);
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress2);
svc.SaveChanges(SaveChangesOptions.Batch);
Try out this code to help you forward to a specific identity provider, if you can figure out how to remember which identity provider they last used. The last login should be stored so that you will automatically 302 back to your app.
public IdentityProvider GetIdentityProvider(string identityProviderName, string realm , string audienceUri )
{
// acs config parameters
string acsNamespace = ConfigurationManager.AppSettings["ida:Namespace"];
realm = realm ?? Uri.EscapeDataString(ConfigurationManager.AppSettings["ida:Realm"]);
audienceUri = audienceUri ?? ConfigurationManager.AppSettings["ida:AudienceUri"];
string returnPath = Uri.EscapeDataString("/home/index");
var newReplyTo =
Uri.EscapeDataString(audienceUri.Replace(new Uri(audienceUri).Authority,
HttpContext.Current.Request.Url.Authority));
// retrieve current identity providers
string idpDiscoveryUrl = string.Format("{0}v2/metadata/IdentityProviders.js?protocol=wsfederation&realm={1}&reply_to={2}&context=rm%3d0%26id%3dpassive%26ru%3d{3}&request_id=&version=1.0", acsNamespace, realm, newReplyTo, returnPath);
string response = null;
using (var client = new WebClient()) {
response = client.DownloadString(idpDiscoveryUrl);
}
List<IdentityProvider> identityProviders = JsonConvert.DeserializeObject<List<IdentityProvider>>(response);
// lookup provider for tenant
var identityProvider = identityProviders.Where(i => i.Name == identityProviderName).FirstOrDefault() ?? new IdentityProvider();
return identityProvider;
}

Resources