I'm having a small issue with implementing custom basic authentication for a asmx in .net 4.0.
I've created the HttpModule which would start the authentication process of the web service consumer runnig this code,
HttpApplication application = (source as HttpApplication);
HttpContext context = application.Context;
if ( VirtualPathUtility.GetFileName(context.Request.FilePath).Contains("svcEWS.asmx"))
{
string username = "", password = "";
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Basic"))
{
//Authenticate here
}
}
However there is no authentication header present whenever this code is reached.
The consuming web app is simply calling,
EWS.svcEWS svcEWS = new EWS.svcEWS();
svcEWS.Credentials = new NetworkCredential("admin", "admin", "example.com");
svcEWS.HelloWorld();
IIS is set to run with anonymous authentication to anonymous authentication to prevent it from catching any auth requests.
Is there something I'm missing to have the client pass the correct header to my module?
I was forgetting to reject the first request with 401 code to force authentication. Doing so fixes the problem, as the invoker re sends the request with the auth header.
Related
I'm using the Quarkus Rest Client to communicate with an external service which uses two cookies to authenticate all requests. These two cookies are returned from an authentication API and from every subsequent API call. Is there a way to handle these cookies automatically? Currently I'm getting the cookies from the response object of the authentication API and I manually send them in every request using #CookieParam.
I haven’t try it, but can’t you do something like this:
//pseudo code !!!
#RestClient
public interface UsersClient {
#POST
String backendCall(#CookieParam("Token1") token1, #CookieParam("Token2") String token2)
#POST
Map<String,String> authenticate(String param)
default String makeCall(String param) {
var tokens = authenticate(param);
return backendCall(tokens.get(0), tokens.get(1));
}
}
From your service you inject this rest client and call the makeCall(...) method. That should authenticate you against your server, and use the tokens from the response and send these as cookies to the backend call.
Apologies for any mistakes in the code: I‘ve written it from my tablet. But I hope the idea is clear.
And also check the Microprofile Rest client documentation for more information:
https://download.eclipse.org/microprofile/microprofile-rest-client-2.0/microprofile-rest-client-spec-2.0.html#_sample_definitions
We have an ASP.NET Core API that uses Windows Authentication and Claim based identity.
The API has one Controller with multiple Actions. The Actions have different authorization policies.
[Authorize(Policy = "Read")]
[HttpGet]
public async Task<ActionResult<Item>> Read()
{ ... }
[Authorize(Policy = "Write")]
[HttpPost]
public async Task<ActionResult<Item>> Write(Item item)
{ ... }
In Startup.cs we have this:
services.AddAuthorization(options => {
options.AddPolicy("Read", policy => policy.RequireClaim("OurReadType","OurReadValue"));
options.AddPolicy("Write", policy => policy.RequireClaim("OurWriteType","OurWriteValue"));
});
We also have a front end that consumes this API. Everything works fine when the front end application accesses our API. Users have only access to read actions if they have the read claim and the same goes for write actions. When a user that has only the read claim tries to call a write action they'll get a 401 Unauthorized. This is all expected behavior. No problems so far.
The problem starts when we try to access our API from Postman. ONLY from Postman do we get 403 Forbidden errors.
Postman is configured to use NTLM Authentication using my personal username and password. And my account has both read and write claims.
If we remove the [Authorize(Policy = "Read")] annotation from an action, we no longer get the 403 error when calling that action using Postman. This makes me think that the problem is somewhere with postman and claims based authorization.
Does anybody have an idea of what the problem is? I'm fairly new to claims based identity and to using Windows authentication to this extent. So any help is appreciated.
I have problem with web service I want to connect to.
In soapUI i used basic authentication with username and password (domain empty), and changed WSS-Password Type to PasswordText and I could without a problem connect to web service. But when I try to connect using c# code:
WebService service = new WebService();
service.ClientCredentials.UserName.UserName = "user";
service.ClientCredentials.UserName.Password = "pass";
service.SomeMethod();
It returns "Forbidden" error.
I need to write a desktop based client application which does some web service method calls to a SharePoint server, after doing a SAML based SSO authentication.
I found that SAML SSO is mostly used from the browser which takes care of all the details. According to this question, it seems there is a technology in SAML 2.0 called ECP just for enabling non browser based clients.
Yet some applications like SharePoint 2010/2013 only support SAML 1.1; what can be used in this case?
You haven't mentioned technology - i can share my experience.
We're required to have a SSO in the desktop application (WPF) that is using the WCF services. I have started with infomation from this link. The solution is to use WIF for retrieving the SAML token from identity provider and using it to establish the connection to our backend server.
To obtain the token
WSTrustChannelFactory GetTrustFactory()
{
var binding = new WS2007HttpBinding(TrustChannelBindingConfiguration);
return new WSTrustChannelFactory(binding, StServiceUri);
}
SecurityToken GetTokenFromSts()
{
using (var trustFactory = GetTrustFactory())
{
// here is the code to set trustFactory.Credentials
trustFactory.TrustVersion = TrustVersion.WSTrust13;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(YourServiceUri),
KeyType = KeyTypes.Bearer
};
var channel = (WSTrustChannel) trustFactory.CreateChannel();
try
{
return channel.Issue(rst);
}
catch (MessageSecurityException msex)
{
channel.Abort();
throw new EMException(msex.InnerException.Message, msex);
}
}
}
Then the obtained token is used in service calls:
securityToken = GetToken();
// 2. Create a channel with issued token to YourServiceInterface
// create binding and turn off sessions
var binding = new WS2007FederationHttpBinding(FederationBinding);
try
{
var factory = new ChannelFactory<YourServiceInterface>(binding,
new EndpointAddress(YourServiceUri));
factory.Credentials.SupportInteractive = false;
var channel = factory.CreateChannelWithIssuedToken(securityToken);
// 3. Call YourMethod() on secured channel
return channel.YourMethod();
}
catch {...}
The main approach from the link hasn't been really changed - we just added token caching and incorporated this code in our channel handling framework.
The code is used to authenticate desktop client against ADFS server and use claims in our backend server for authorizations.
We have converted a WSDL file of a Web serivice into the salesforce apex classes. The Web Service is receiving the authentication credentials in Apache axis Stub authentication username and password format.
Below is the sample Apache axis Stub authentication username and password code.
Service service = new XYZServiceLocator();
URL endpointURL = new URL("https://urllink");
XYZServiceSoapBindingStub stub = new XYZServiceSoapBindingStub(endpointURL, service);
stub.setUsername("username");// void org.apache.axis.client.Stub.setUsername(String username)
stub.setPassword("password");// void org.apache.axis.client.Stub.setPassword(String Password)
QueryResponse qresp = stub.webServiceCall(qr);
My question is. Can we get the Apache axis Stub authentication username and password functionality in the salesforce Apex classes.
As the Apex Stub support the HTTP Headers authentication does it also support the Apache axis Stub authentication?
Below is the Salesforce Apex stub HTTP Headers authentication code
String myData = 'username:password';
Blob hash = Crypto.generateDigest('SHA1',Blob.valueOf(myData));
encodedusernameandpassword = EncodingUtil.base64Encode(hash);
XYZBillingStub.inputHttpHeaders_x.put('Authorization','Basic ' + encodedusernameandpassword );// SALESFORCE STUB
XYZBilling.query(queryReq )// Web Service call
Please help me in resolving this issue.
After converting the apex code to the below code I was successfully able to resolve the issue.
String myData = 'username:password';
encodedusernameandpassword = EncodingUtil.base64Encode(Blob.valueOf(myData));
XYZBillingStub.inputHttpHeaders_x.put('Authorization','Basic ' + encodedusernameandpassword );// SALESFORCE STUB
XYZBilling.query(queryReq )// Web Service call
This was a simple hit and trial solution I got, And I think Salseforce apex functionality only support input HTTP Headers authentication process. If one has some other way to do the authentication please mention it.
Looks like you already figured out a solution.
For reference, have a look at the Sending HTTP Headers on a Web Service Callout section of the online docs for doing basic authentication headers.