Im running a exchange synchronisation application with an autogenerated Proxy Class in .NET built with Exchange2010.
Now, i need to set the HttpHeaders:
service.HttpHeaders.Add("X-AnchorMailbox", Mailbox.SMTPAddress);
service.HttpHeaders.Add("X-PreferServerAffinity", "true");
like described here:
Maintain affinity in exchange
But it refers to the EWS Managed API and i cannot find this Property in my ExchangeServiceBindingObject. So how can I set this header in my autogenerated proxy?
I would try to use the EWS Managed Api rather than trying to roll your own. If that if that is not an option, you can add httpheaders by overriding the generated GetWebRequest method on ExchangeServiceBinding to get to the headers like so:
public class ExchangeServiceBindingWithHeaders : EwsProxy.ExchangeServiceBinding
{
private NameValueCollection _customHeaders = new NameValueCollection();
public void AddHeaders(string key, string value)
{
_customHeaders.Add(key, value);
}
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(uri);
req.Headers.Add(_customHeaders);
return req;
}
}
Then you can call the new derived class to add the custom headers:
ExchangeServiceBindingWithHeaders service = new ExchangeServiceBindingWithHeaders();
service.RequestServerVersionValue = new RequestServerVersion();
service.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2010;
service.Credentials = new NetworkCredential("<username>", "<password>", "<domain>");
service.Url = #"https://<FQDN>/EWS/Exchange.asmx";
service.AddHeaders("X-AnchorMailbox", "some#emailaddress.com");
service.AddHeaders("X-PreferServerAffinity", "true");
Related
I have a spring boot application that has the below AuthFilter added for all rest apis exposed by the application. I want to test the below code that validates authorization token by calling a third party api call. I tried Mockito but how do I inject the mocked HttpPost, HttpClient etc object in the filter class?
Also what value do I pass to thirdPartyAPIUrl property which is configured in application.properties for test class
#Component
public class AuthTokenFilter implements Filter {
public boolean isAuthTokenValid(HttpServletRequest request, HttpServletResponse response) throws IOException {
String authorizationToken = request.getHeader(RequestHeaders.AUTHORIZATION.toString());
TokenRequest validateTokenRequest = new TokenRequest();
validateTokenRequest.setToken(authorizationToken);
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(this.thirdPartyAPIUrl); //fetched through application.properties
httpPost.setHeader("Content-type", "application/json");
StringEntity requestBody = new StringEntity(new Gson().toJson(validateTokenRequest));
httpPost.setEntity(requestBody);
try (CloseableHttpResponse validateTokenResponse = httpclient.execute(httpPost)) {
HttpEntity rEntity = validateTokenResponse.getEntity();
TokenResponse tokenResponse = new ObjectMapper().readValue(rEntity.getContent(),
TokenResponse.class);
logger.debug("API Response Object : {}", tokenResponse);
}
}
return false; //temporary
}
}
Thanks!
I would recommend avoiding mocking HttpPost etc and instead just mocking the third-party server. My preferred tool to use for this is wiremock
Here is an example of how it would be used:
(make sure to import this for options, caused me a lot of headaches ;) )
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
... code
static WireMockServer wireMockServer = new WireMockServer(options().port(8080));
#BeforeAll
static void init() {
wireMockServer.start();
}
//this is for the case that you have multiple test suites that mock the server, to avoid conflicts with ports
#AfterAll
static void releaseResource() {
wireMockServer.stop();
}
#Test
void test() {
wireMockServer.stubFor(post("/endpoint").willReturn(aResponse().withStatus(200)));
... more code
filter.isAuthTokenValid(request, response);
}
I have a Spring web client which posts to a Spring web server (the same URL) using two different basic-auth users. Is it a known issue that I can not use a single RestTemplate for both?
When I use a single RestTemplate, and the requests are nearly simultaneous (in different threads), though I specify different users in the header, the receiving server thinks they're from the same user! Note that the request and the headers (and the body of the post) are newly allocated for each request.
It works fine, when I use a single RestTemplate and put a synchronized() around the call to
response = RestTemplate.exchange(url, method, requestParams, MyResponse.class)
I've also tried creating two RestTemplate instances, one for each user - (each built with a RestTemplateBuilder) that works, too. I'll keep this solution, but it surprises me that it's needed.
Is this a known issue?
(I see stackOverflow answers that a RestTemplate is thread-safe after constructed, but the headers are passed in with the request, not as a setting on the already-constructed RestTemplate...)
====
Here's an example of 2 different calls, using 2 different RestTemplates because there were sometimes problems in using the same:
public OperationStatus getOpStatus(String gufi) {
HttpEntity<String> requestParams = new HttpEntity<>(Utils.createBasicHeader(cfg.getManager(), cfg.getManPass()));
ResponseEntity<OperationStatus> restResponse = null;
try {
restResponse = managerRestTemplate.exchange(
cfg.getNussOpApiPath(), HttpMethod.GET, requestParams, OperationStatus.class);
} catch (RestClientException e) {
...
}
OperationStatus opState = restResponse.getBody();
opState.setHttpStatusCode(String.valueOf(restResponse.getStatusCodeValue()));
return opState;
}
Here was a method to do a post, using the priority to switch rest templates (at the time, the target server recognized the priority by the privileges of the user)
UTMRestResponse doPost(Object objToSend, String url, String msg) throws IOException {
String user = cfg.getOpUser();
String pass = cfg.getOpPass();
RestTemplate restTemplate = opUserRestTemplate;
boolean isPriorityOp = false;
if ( objToSend instanceof OpPost) {
OpPost post = (OpPost) objToSend;
String flightNum = post.getFlightNumber();
isPriorityOp = Boolean.TRUE.equals(post.getPriorityOp()); // null is false
} else if ( objToSend instanceof PositionPost) {
PositionPost post = (PositionPost) objToSend;
isPriorityOp = Boolean.TRUE.equals(post.getPriorityOp()); // null is false
}
if (isPriorityOp) {
user = cfg.getUserEmergency();
pass = cfg.getPassEmergency();
restTemplate = emergRestTemplate;
}
String jsonToSend = CommonsObjectMapper.get().writeValueAsString(objToSend);
HttpEntity<String> requestParams = new HttpEntity<>(jsonToSend, Utils.createBasicHeader(user, pass));
UTMRestResponse restResponse = restTemplate.exchange(
url, HttpMethod.POST, requestParams, UTMRestResponse.class).getBody();
if (restResponse.getHttpStatusCode().startsWith("4")) {
String fmt = "Status:{}, url:{}, jsonSent:{}, response:{}";
logger.error(fmt, restResponse.getHttpStatusCode(), url, jsonToSend, restResponse.getMsg());
}
return restResponse;
}
In my application, I need to take data from another request and chain into a new one
I must use the exchange() method of RestTemplate because I have issue with jacksons lib and I cannot add/change the libs.
this is my code:
final RequestCallback requestCallback = new RequestCallback() {
#Override
public void doWithRequest(final ClientHttpRequest request) throws IOException {
request.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
// Add basic auth header
String auth = username + ":" + password;
byte[] encodedAuth = Base64Utils.encode(auth.getBytes(StandardCharsets.US_ASCII));
String authHeader = "Basic " + new String(encodedAuth);
request.getHeaders().add("Authorization", authHeader);
// Add Headers Request
Enumeration headerNamesReq = servletRequest.getHeaderNames();
while (headerNamesReq.hasMoreElements()) {
String headerName = (String) headerNamesReq.nextElement();
if (whiteListedHeaders.contains(headerName.toLowerCase())) {
String headerValue = servletRequest.getHeader(headerName);
request.getHeaders().add(headerName, headerValue);
}
}
request.getHeaders().forEach((name, value) -> {
log.info("RestExecutorMiddleware", "HEADERS ---\t" + name + ":" + value);
});
IOUtils.copy(new ByteArrayInputStream(payload.getBytes()), request.getBody());
}
};
// Factory for restTemplate
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
ClientHttpResponse responsePost = restTemplate.execute(url, method, requestCallback, new ResponseFromHeadersExtractor());
But at the end, the endpoint cannot receive my JSON (receive data, but not JSON.)
Where I wrong?
Thanks
Very inaccuracy code. Make all steps one-to-one and it will work, you make optimization later ...
Basic Auth. Don't do unnecessary actions
var headers = new HttpHeaders();
headers.setBasicAuth(username, password);
That's all, Spring will take care of everything else - to apply Base64, add Basic: and set properly a header.
Set all required headers including headers.setContentType(MediaType.APPLICATION_JSON)
Get an entity/object which you need to send (set as a body) with a request.
Serialize your object. The most popular, proper and simple way is using fasterxml json framework, you can make serialization with mapper.writeBalueAsString(<your object>). If you really cannot use external libraries, HttpEntity should make it: var request = new HttpEntity<>(<object>, headers);
Make restTemplate request. In almost all cases more convenient methods are restTemplate.postForObject(), restTemplate.getForObject(), restTemplate.postForEntity(), etc.: restTemplate.postForObject(uri, request, ResponseObject.class)
I am trying to authenticate my app using ADFS and oauth2. I found a lot of documentation to do this with an azure service (using ADAL). But there is no info about how to do it with a local server.
I tested all the info below with an angular app and the authentication works!
public class AuthenticationService
{
public static string clientId = "uri:tst-amdm-website.mycompany.be";
private static string commonAuthority = "https://claim.mycompany.be/";
public static Uri returnUri = new Uri("http://www.google.be");
const string graphResourceUri = "uri:tst-amdm-api.mycompany.be";
public async void GetAccessToken(IPlatformParameters platformParameters)
{
AuthenticationResult authResult = null;
JObject jResult = null;
//List<User> results = new List<User>();
try
{
AuthenticationContext authContext = new AuthenticationContext(commonAuthority);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
authResult = await authContext.AcquireTokenAsync(graphResourceUri, clientId, returnUri, platformParameters);
var test = authResult.AccessToken;
}
catch (Exception ee)
{
//results.Add(new User { error = ee.Message });
//return results;
}
}
}
This is the error I get, but in angular this url: https://claim.mycompany.be/ works perfectly.
'authority' Uri should have at least one segment in the path (i.e. https://<host>/<path>/...)
There's good references here but note that you need ADFS 4.0 to do this.
For ADFS 3.0. your choices are limited. Good overview here.
I am creating a simple authentication server using the default owin oauth server. After supplying the correct credentials a bearer token is generated and returned to the client. I used among others this tutorial by Taiseer
I would like to store the token in a database before the token is send to the client.
Maybe I completely overlooked it, but where can I get the token before it is send? As far as I know the token is generated after the ticket is validated in the GrantResourceOwnerCredentials method.
I am guessing the token is stored in the context. How can I get it out?
Startup.cs
private void ConfigureAuthServer(IAppBuilder app) {
// Configure the application for OAuth based flow
var oAuthServerOptions = new OAuthAuthorizationServerOptions {
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth/token"),
Provider = new ApplicationOAuthProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
ApplicationOAuthProvider
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) {
//Dummy check here
if (context.UserName != context.Password) {
context.SetError("invalid_grant", "The user name or password is incorrect");
return Task.FromResult<object>(null);
}
var claims = new List<Claim> {
new Claim(ClaimTypes.NameIdentifier, context.UserName),
new Claim(ClaimTypes.Name, context.UserName)
};
var oAuthIdentity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);
return Task.FromResult<object>(null);
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context) {
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary) {
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
Note: for those who wonder why I want to store the tokens.. it is a requirement I have to fulfill.
To fetch the token before it is sent to the client you must override TokenEndpointResponse:
public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
{
return base.TokenEndpointResponse(context);
}
the context object has a property AccessToken which will contains the representation of the token as a string.
OAuthTokenEndpointResponseContext contains a dictionary of objects
IDictionary<string, object> in AdditionalResponseParameters which allows us to find all the claims for the indentity.
If we wanted to fetch the expiration of the token we would find the claim .expires in the dictionary:
context.AdditionalResponseParameters[".expires"]
There's a github repository if someone is interested to play with a simple integration of client and server interaction.