Configuration of assertion valid to datetime - itfoxtec-identity-saml2

I'm implementing NemLog-in3 / OIOSAML 3 authentication in my .NET Core web application. With great success so far. I only have this one question about the security token validation, when getting the assertion from the IdP, after authentication.
When i get the assertion from the IdP, it has a SecurityToken in the response, with a validFrom and a validTo Datetime. The difference is +1 hour, but in the OIOSAML3 test documentation, it says to "invalidate" the assertion and that your SP should reject the user from logging in after 5 minutes.
Do you know if it's possible to configure the securityToken valid period (set it to 5 minutes), perhaps when initiating the SAML authentication? I know i could just check the validTo and add 5 minutes to it, but i'd rather have it working dynamically, with the validTo property, if possible.

The Conditions elements NotBefore and NotOnOrAfter is valid for an hour, which is correct. The 5 minutes login restriction should have been in the SubjectConfirmation element NotOnOrAfter. It looks like an error in NemLog-in3?
NemLog-in3 SAML 2.0 authn response:
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" SPNameQualifier="https://saml.itfoxtecidentitysaml2-public-dev.sample">
https://data.gov.dk/model/core/eid/professional/uuid/8e190635-4a9c-4748-91ed-24895f809647
</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="_29a72131-ab30-4429-b083-b18db2d6160e" NotOnOrAfter="2021-09-08T13:22:32.062Z" Recipient="https://localhost:44310/Auth/AssertionConsumerService"/>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2021-09-08T12:22:31.843Z" NotOnOrAfter="2021-09-08T13:22:31.843Z">
<AudienceRestriction>
<Audience>
https://saml.itfoxtecidentitysaml2-public-dev.sample
</Audience>
</AudienceRestriction>
</Conditions>

Related

Access package assignment approval update via MSGraph API returns HTTP 403: Only user tokens are supported

I'm trying to call Access package assignment approval update via MSGraph Beta API (Java 0.51.0-SNAPSHOT). The call fails with following error:
2022-08-26 22:32:44.239 ERROR 10208 --- [nio-9999-exec-4] global : CoreHttpProvider[sendRequestInternal] - 408Graph service exception
2022-08-26 22:32:44.239 ERROR 10208 --- [nio-9999-exec-4] global : Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code:
Error message: Only user tokens are supported
PATCH https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/steps/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
SdkVersion : graph-java/v0.51.0
[...]
403 : Forbidden
[...]
[Some information was truncated for brevity, enable debug logging for more details]
Based on the error message can I think, that Application tokens are not really supported, but the strange thing is, that I can call Access package assignment approval get without any issue. I have of course delegated the permission EntitlementManagement.ReadWrite.All to the Application user.
I tried to reproduce the same in my environment using Graph Explorer and got the below results:
I am able to retrieve the properties of an approval object successfully like this:
GET https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/<id>
Response:
To update those properties, I ran the same query as you like below, and it got updated successfully:
PATCH https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/<id>/steps/<id>
{
"reviewResult": "Approve",
"justification": "Please approve"
}
Response:
Make sure to pass 'Request body' with the PATCH query. Please check whether you are giving correct id's or not in the query.
The <id> before /steps/ in the query is the id of accessPackageAssignmentRequest that is in PendingApproval State.
To get that id, you can run the below query:
GET https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentRequests?$expand=requestor($expand=connectedOrganization)&$filter=(requestState eq 'PendingApproval')
Response:
The <id> after /steps/ in the query is the step id that I got by running below query:
GET https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/<id_that_you _got_in_above_query>
Response:
UPDATE
Please note that, you cannot update Access package assignment approval using Application permissions. Application permissions are not supported for PATCH query.
You can refer this MsDoc to confirm that like below:
So, it will only work if you login with work or school account(personal-login)

Getting error asInvalidSession id while invoking upsert bulk operation in mule salesforce connector

Polling app daily once. We are loading data using upsert bulk operation in salesforce. First day it is working fine . Second day on wards we are getting the below error(InvalidSession id ). I found workaround as reconnection strategy and configured even after it is not working.
[2017-06-07 10:02:24.519] ERROR org.mule.retry.notifiers.ConnectNotifier [[test-salesforce-bulk].checkbulkupsert.stage1.05]: Failed to connect/reconnect: Work Descriptor. Root Exception was: InvalidSessionId : Invalid session id. Type: class com.sforce.async.AsyncApiException
[2017-06-07 10:02:24.547] ERROR org.mule.exception.CatchMessagingExceptionStrategy [[test-salesforce-bulk].checkbulkupsert.stage1.05]:
********************************************************************************
Message : Failed to invoke upsertBulk.
Element : /test-salesforce-bulk/processors/4/prepareAccountRequestSubFlow/subprocessors/1 # test-salesforce-bulk
--------------------------------------------------------------------------------
Exception stack is:
Failed to invoke upsertBulk. (org.mule.api.MessagingException)
com.sforce.async.BulkConnection.parseAndThrowException(BulkConnection.java:180)
com.sforce.async.BulkConnection.createOrUpdateJob(BulkConnection.java:164)
com.sforce.async.BulkConnection.createOrUpdateJob(BulkConnection.java:132)
com.sforce.async.BulkConnection.createJob(BulkConnection.java:122)
org.mule.modules.salesforce.SalesforceConnector.createJobInfo(SalesforceConnector.java:2570)
org.mule.modules.salesforce.SalesforceConnector.upsertBulk(SalesforceConnector.java:672)
org.mule.modules.salesforce.generated.processors.UpsertBulkMessageProcessor$1.process(UpsertBulkMessageProcessor.java:153)
(50 more...)
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
Can you please help on this.
There error says Invalid Session Id.
This means that the initial session has expired. Check your login history and see if there's even an attempt to login. If there's not, you need to update your username in Mulesoft. If there is and it was unsuccessful, you need to update your password/security token. If there is and it was successful, then it could be that your Session Settings are set to limit calls to the initial IP address or something like that.

Getting Claims from ADFS 3.0 and Displaying To Shibboleth 2.6 Service Provider (SP) in SAML 2.0

I'm trying to configure Windows Server 2012 r2 ADFS 3.0 to send the NameID to Shibboleth 2.6 SAML 2.0 SP, but I keep on getting these errors:
2016-11-15 10:07:07 WARN Shibboleth.AttributeResolver.Query [1]: can't attempt attribute query, either no NameID or no metadata to use
2016-11-15 10:07:07 INFO Shibboleth.SessionCache [1]: new session created: ID (_7e425978e43bc32c86393f518b26eb3e) IdP (https://c-adfs01.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml) Protocol(urn:oasis:names:tc:SAML:2.0:protocol) Address (192.168.50.131)
I understand that this has something to do about passing the NameID attribute from the ADFS IDP and displaying the nameID in Shibboleth SAML 2.0 SP.
I've also read that you need to set a rule in ADFS IDP to pass the Email Address, and transform the Email address to become a NameID. I have done that, and have these rules:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
=> issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
However, I have observed that the configuration seems compatible only with SAML 1.0, but not 2.0 (maybe).
So, I went on by adding the name attributes. I tried transient, persistent, and emailAddress, and trying both SAML 1.0 and SAML 2.0 configurations.
<Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" id="NameID"/>
<Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="NameID"/>
<Attribute name="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" id="NameID"/>
Question:
So, what is the proper way of configuring ADFS IDP to send the NameID to the Shibboleth SP and display the Session attribute when going to my application Session page?
Specifically, what is the proper output for Claim Rules that I should expect? and how should the XML configuration for Shibboleth attribute-map.xml look like?
https://c-app01.contoso.com/Shibboleth.sso/Session
Solution:
The solution is to create two rules inside "Issuance Transform Rules" tab in the Relying Party. Here are the Rules to be set:
Add a Rule to Send LDAP Attributes as Claims
Add a Rule to Transform an Incoming Claim
Also, make sure that Permit Access to All Users is inside Issuance Authorization Rules tab.
Instructions:
Add a Rule to Send LDAP Attributes as Claims:
Claim Rule Name: Email
Attribute Store: Active Directory
Mapping of LDAP: E-mail-Address to E-mail Address
This will map the Email address.
Add a rule to Transform An Incoming Claim:
Claim rule name: EmailToNameID
Incoming Claim Type: E-Mail Address
Outgoing Claim Type: Name ID
Outgoing Name ID Format: Email
Make sure "Pass Through Claim Values" is selected.
The setting above for "Transform An Incoming Claim" will give you the following claim rule:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
=> issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
After that, you may configure the attribute-map.xml like so:
<Attribute name="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" id="Email"/>
My Mistake:
I found out that every setting in my Claims Rules is correct, except that the rules for Email and EmailToNameID should be under the Issuance Transform Rules Tab of the Relying Party.

WS-Policy X509Token with Supporting Tokens

I have a WSDL that contains WSPolicy, the policy defined uses supporting tokens and with-in supporting tokens it uses X509 Tokens. Below is a snippet of the WSDL having the policy
<wsp:Policy xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wssutil:Id="MyPolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Now when I generate my client (using Apache CXF), consume any web service operation, I don't see the wssec security header getting added to the SOAP header. As a result, the SOAP service throws error as the Policy Validation Interceptor fails.
I have done a lot of search and have not found any sample / example using this kind of policy, supporting tokens have been used along with Assymetric / Symmetric bindings.
Want to know if the policy defined is correct, if yes, then what will be the client code to access this service.
Just to add, when I put below interceptor into the client code, the security header gets added (with a Binary Security Token and Signature), however, the service still fails (with Policy Verification Interceptor)
Client client = ClientProxy.getClient(port);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.USER, "myclientkey");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientKeystorePasswordCallback.class.getName());
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "clientKeystore.properties");
outProps.put(ConfigurationConstants.SIG_KEY_ID, "DirectReference");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
client.getOutInterceptors().add(wssOut);
Below is the error stack trace
Caused by: org.apache.cxf.binding.soap.SoapFault: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SupportingTokens
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1638)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1527)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1330)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:638)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
... 2 more
Any help will be much appreciated!! I am stuck with this issue since 2 days.
Using a BinarySecurityToken as a SupportingToken with no security binding won't work with CXF. You need to specify a security binding in order to sign the request as well.

Silverlight RIA Services - How To Best Handle Client Auth Session Timeout?

I built an app with Silverlight4, RIA Services, and I'm using ASP.NET Membership for authentication/authorization.
My web.config has this:
<system.web>
<sessionState timeout="20"/>
<authentication mode="Forms">
<forms name="_ASPXAUTH" timeout="20"/>
</authentication>
I have read a number of different strategies on how to deal with auth/session timeout on the client side. That is: if the client is idle for x minutes (20 here), and then they do something with the UI that triggers a RIA/WCF call, I want to trap on that event and deal with appropriately (e.g. take them back to the login screen) -- in a nutshell: I need a way to differentiate from a bona-fide server side DomainException vs. an auth failure because the session timed out.
AFAIK: there is no typed exception or property that can determine this. The only way I've been able to determine this -- which seems like a hack: is to inspect the Error's Message string and look for something like "Access denied" or "denied". For example: something like this:
if (ex.Message.Contains("denied"))
// this is probably an auth failure b/c of a session timeout
So, this is what I'm currently doing, and it works if I run and debug either with the built-in server from VS2010, or if I run in localhost IIS. If I set the timeout to 1 minute, login, wait more than a minute and trigger another call, I breakpoint on the exception and enter the if code block above and all is well.
Then I deploy the app to a remote IIS7 server and I try the same test and it doesn't work. So, I added log tracing, and here's the event where the exception happened:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131076</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2011-10-30T22:13:54.6425781Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{20c26991-372f-430f-913b-1b72a261863d}" />
<Execution ProcessName="w3wp" ProcessID="4316" ThreadID="24" />
<Channel />
<Computer>TESTPROD-HOST</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier>
<Description>Handling an exception.</Description>
<AppDomain>/LM/W3SVC/1/ROOT/sla-2-129644844652558594</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.FaultException`1[[System.ServiceModel.DomainServices.Hosting.DomainServiceFault, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message></Message>
<StackTrace>
at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior`1.QueryOperationInvoker.InvokeCore(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.DomainServices.Hosting.DomainOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
</StackTrace>
<ExceptionString>System.ServiceModel.FaultException`1[System.ServiceModel.DomainServices.Hosting.DomainServiceFault]: (Fault Detail is equal to System.ServiceModel.DomainServices.Hosting.DomainServiceFault).</ExceptionString>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
The problem is that I don't have the string in the error message that indicates "denied" or "Access denied" - and I am unsure as to why this solution works in localhost IIS or VS2010 host but not in a remote IIS7 server. Is there some obscure configuration setting that I'm missing here? Is there a better way to do this in general?
You've probably gotten by this by now, but this article describes using the DomainOperationException and checking the error codes.
dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized
For convenient access (and in case the we loose access to the blog) here's the blog article by Josh Eastburn:
A question that comes up often from developers who are working with Silverlight and WCF RIA Services: why does my Silverlight application throw an exception when it has been idle for a period of time? As you might expect, it is due to the authenticated session timing out. But it isn’t quite that straightforward. Because Silverlight uses a client/server architecture, the client can operate independent of the server for an indefinite period of time. It is only when the Silverlight client makes a call to the server that the server-side timeout is realized. There are a few options to handle the client-server timeout issue (and you may be able to come up with a few more): If you aren’t concerned with the security implications of removing a session timeout, you can either increase the timeout setting in web.config, or create a DispatcherTimer in the Silverlight client that calls a simple method on the server to act as a "Keep Alive." Add a DispatcherTimer to the Silverlight client that stays in sync with the server-side timeout and warn/prompt the user keep the session active before the time expires or have them re-authenticate if it has already expired. However, this requires extra effort to keep the timers in sync when new server requests are made. Allow the server to handle the timeout as it normally would and handle the timeout gracefully on the Silverlight client. This means that the timeout is determined by server call activity, NOT activity confined the Silverlight client (i.e. accessing client-side data in the context). Of these three options, I find the third to be the best balance of security and usability while at the same time not adding unnecessary complexity to the application. In order to handle these server-side timeouts globally, you can add the following logic in either the Application_UnhandledException method in App.xaml.cs or in your global ViewModel loading construct if you have one:
// Check for Server-Side Session Timeout Exception
var dex = e.ExceptionObject as DomainOperationException;
if ((dex != null) && (dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized) && WebContext.Current.User.IsAuthenticated)
{
// A server-side timeout has occurred. Call LoadUser which will automatically
// authenticate if "Remember Me" was checked, or prompt for the user to log on again
WebContext.Current.Authentication.LoadUser(Application_UserLoaded, null);
e.Handled = true;
}
The following constants are defined within the ErrorCodes class:
public static class ErrorCodes
{
public const int NotAuthenticated = 0xA01;
public const int Unauthorized = 401;
}
When the server-side session times out, any subsequent calls will return a DomainOperationException. By inspecting the returned ErrorCode, you can determine if it is an authentication error and handle it accordingly. In my example, I am calling WebContext.Current.Authentication.LoadUser() which will attempt to re-authenticate the user if possible. Even if the user can not be automatically re-authenticated, it will call back to my Application_UserLoaded method. There I can check WebContext.Current.User.IsAuthenticated to determine whether to proceed with the previous operation or if I need to redirect back to the home page and reprompt for login. Here is an example of some code in the Appliation_UserLoaded callback that shows a login dialog if the user is not authenticated:
// Determine if the user is authenticated
if (!WebContext.Current.User.IsAuthenticated)
{
// Show login dialog automatically
LoginRegistrationWindow loginWindow = new LoginRegistrationWindow();
loginWindow.Show();
}
To test your code, you can set your timeout value in web.config to a
small value so timeouts occur quickly:
<authentication mode="Forms">
<forms name=".Falafel_ASPXAUTH" timeout="1" />
</authentication>
If you’d like to see all of this code in a working solution, check out our Silverlight RIA Template on CodePlex.

Resources