Am using spring security version 3.2. Am adding headers such as X-Frame-options, X-content-type-options in the response headers of the authenticated request.
<sec:http auto-config="false">
<sec:headers>
<sec:frame-options policy="DENY" />
<sec:content-type-options />
<sec:xss-protection enabled="true" block="true" />
</sec:headers>
</sec:http>
but those headers are not get adding in the security none request.
<sec:http security="none" pattern="/spring/loginpage" />
what might be the reason?
Because if there's no security on that pattern, then Spring Security isn't activated.
Make your own Interceptor, like this:
public class SecurityHeadersInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
response.setHeader("Strict-Transport-Security","max-age=31536000 ; includeSubDomains");
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("Content-Security-Policy", "default-src 'self'");
super.postHandle(request, response, handler, modelAndView);
}
}
In mvc-dispatcher-servlet.xml add:
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.example.interceptor.SecurityHeadersInterceptor"/>
</mvc:interceptor>
You should set Cache-Control: no-store, must-revalidate on any private responses too (incl if contains CSRF token, like a login form).
Related
I am using spring 4.2.1 with spring security 4.0.2
On login, I need to return a json object tree to the client, containing the cached data it requires for the session.
So I've added a the following method:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public #ResponseBody ServerResponse<?> login(#RequestBody LoginRequest loginRequest, HttpServletRequest request, HttpServletResponse response) {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
Authentication result = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(result);
Object data = null; // Do stuff here
return new ServerResponse<>(data);
}
My spring security config:
<ss:http auto-config="false" use-expressions="true" entry-point-ref="authenticationEntryPoint">
<ss:anonymous enabled="false" />
<!-- this is enabled by default in spring 4 -->
<ss:csrf disabled="true" />
<ss:custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
<ss:session-management session-authentication-strategy-ref="sas" />
<ss:port-mappings>
<ss:port-mapping http="8080" https="8443" />
</ss:port-mappings>
<ss:intercept-url pattern="/app/logi**" access="permitAll()" />
<ss:intercept-url pattern="/app/logou**" access="permitAll()" />
<ss:intercept-url pattern="/app/**" access="hasAuthority('user')" />
<ss:intercept-url pattern="/www/**" access="hasAuthority('user')" />
</ss:http>
All the pages I find regarding a programmatic login confirm that what I am doing is fine.
However, when I try and call another web service method later, I get 403 as the client is not logged in.
I read some vague references to having to use a spring filter, but I am not sure how I would get the filter to return the json tree to the client after successful login.
Any suggestions or links to an example on how to do this would be much appreciated.
Thanks
Sooo it turns out the problem was that I was doing Cross Origin Resource Sharing and the browser was not sending the cookie across with the next request.
Basically I was calling the server from html on the file system (with origin file://)
I was handling options calls, but I was not sending back
Access-Control-Allow-Credentials true
headers in the responses and I had to configure angular to send the cookie by passing the flag
withCredentials: true
in the config object to $http.post
In my application i am using web api with token based authentication with CORS support, but when client request for the token, an error occured due to CORS (Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at (my site name) . This can be fixed by moving the resource to the same domain or enabling CORS.)
I had configured everything required for CORS support ( i think so). here my configuration
Owin start up class
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration
{
DependencyResolver = new StructureMapWebApiDependencyResolver(container)
};
WebApiConfig.Register(config); // registering web api configuration
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); // cors for owin token pipeline
app.UseWebApi(config);
ConfigureOAuth(app);
}
public void ConfigureOAuth(IAppBuilder app)
{
var oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
And my webapi configuration
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors(); // Corse support for Web api
config.MapHttpAttributeRoutes(); // attribute based urls
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
here configuration in web.config
<system.webserver>
<httpProtocol>
<customHeaders>
<!-- Adding the following custom HttpHeader will help prevent CORS from stopping the Request-->
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</customHeaders>
</httpProtocol>
</system.webserver>
and my request header from mozilla
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length 67
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Host talenterp
Origin http://192.168.1.11:85
Referer http://192.168.1.11:85/
User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
The URLs of Apps are
Server app (which should support CORS)
{http://talenterp}
Token end point :
{http://talenterp/token}
Client app
{http://talentmvc:85}
NB: I already added
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
in GrantResourceOwnerCredentials() method of my AuthorizationServerProvider
Be sure you've got only
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
configured, and not also the old style 'config.EnableCors()' in your Global.asax or WebApiConfig. Furthermore: place the above statement as the first one in your owin Startup class. Yes that really makes a difference, setting it later can also cause cors to not work.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
... etc
OWIN and Microsoft.AspNet.WebApi.Cors are two separate libraries and each one needs separate configuration.
Disable use of CORS with OWIN:
public void Configuration(IAppBuilder app)
{
//app.UseCors(CorsOptions.AllowAll);
Find GrantResourceOwnerCredentials method and add Access-Control-Allow-Origin to context so when it returns a call after authentication is completed that browser finds the header and accepts it.
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost" });
Now install Microsoft.AspNet.WebApi.Cors package from Nuget to your webapi project, and add this to Register method
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("http://localhost, ", "accept,accesstoken,authorization,cache-control,pragma,content-type,origin", "GET,PUT,POST,DELETE,TRACE,HEAD,OPTIONS");
config.EnableCors(cors);
This did it for me.
Especially if you are having problem with the Web API bearer token when using CORS then dont forget to put "TOKEN" in the list of your allowed methods.
Please put the code in your system.webServer of web.config, that is how i solved mine
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE, TOKEN" />
</customHeaders>
Had the same problem. In addition to the above indications (using app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll) only, and setting it up as first thing), I had to specify the following in the application Web.config file to be able to handle Option Requests:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
Due to some headers that I was sending in the authentication request, an Options request is sent before the actual POST request, and it needs to return the correct 'Access-Control-Allow-Origin' header before the POST is sent.
If none of the CORS headers are returned by the options response, then the POST will not be sent at all. The added configuration enables this behaviour as well as for Trace.
As explained in this post
I had this similar problem, I tried all the options above in startup.cs i added app.UseCors(CorsOptions.AllowAll); at the top and in the WebApiConfig i disabled
public static void Register(HttpConfiguration config)
{
//var cors = new EnableCorsAttribute("*", "*", "*");
//config.EnableCors(cors);
}
and also disabled cors in
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
}
And repeated this in reverse order and also included entries in web.config but all did not work.
When I begun asking myself why is app.UseWebApi(config); not accessible yet I have seen it work somewhere. I looked around and found out installing Install-Package Microsoft.AspNet.WebApi.OwinSelfHost fixes it.
Eventually, it fixed the whole problem, though app.UseCors(CorsOptions.AllowAll) has to be placed first in the startup.cs method. In fact without app.UseWebApi(config), I tested in postman and the end points actually didn't exist. Overall it's working pretty well for me now.
I'm using spring/spring-security 3.1 and want to take some action depends on the authorities in ATHENTICATION object whenever session is timed out.AUTHENTICATION object is null on session timeout.
Here are the files for reference:
security config:
<logout invalidate-session="true" logout-url="/j_spring_security_logout" success-handler-ref="logoutSuccessHandler"/>
<!-- Custom filter to deny unwanted users even though registered -->
<custom-filter ref="blacklistFilter" before="FILTER_SECURITY_INTERCEPTOR" />
<!-- Custom filter for username, password and domain. The real customization is done in the customAuthenticationManager -->
<custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER" />
</http>
Note: tried with "invalidate-session="false"" as well.
and my custom LogoutSuccessHandler:
public class EnterpriseLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler{
#Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
for(GrantedAuthority authority: authentication.getAuthorities()){
if(authority.getAuthority()!=null)
logger.debug("THE CURRENT AUTHORITY FOR THE SESSION IS : {} ",authority.getAuthority().toString());
else
logger.debug("THE CURRENT AUTHORITY FOR THE SESSION IS authority.getAuthority(): NULL ");
if(authority.getAuthority()!=null && authority.getAuthority().equalsIgnoreCase(Operational.SPRING_SECURITY.LOGIN_SOURCE_BEACON)){
loginSource = authority.getAuthority().toString();
break;
}
}
}
}
So, there is the question how I can obtain Authentication object on the session timeout.
Can some help me to find out the solution for the above problem.
Thanks in advance.
How do I setup digest auth type to webservice client using cxf (JaxWsProxyFactoryBean) ? As of now my client by default assumes Basic auth type when I set the username password in the factory object. And the request message header have "Authentication [Basic: ......]" in it. I want to setup a cxf client for digest auth. could you please assist ?
(WS is implemented in Java using CXF and Spring 3)
I have configured spring security for Digest auth as follows...
<security:http entry-point-ref="digestEntryPoint">
<security:intercept-url pattern="/**" requires-channel="any" access="ROLE_WS_USER" />
<security:custom-filter ref="digestAuthenticationFilter" position="BASIC_AUTH_FILTER"/>
</security:http>
<bean id="digestAuthenticationFilter" class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
<property name="userDetailsService" ref="userService"/>
<property name="authenticationEntryPoint" ref="digestEntryPoint"/>
</bean>
<bean id="digestEntryPoint" class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
<property name="realmName" value="My Webservice"/>
<property name="key" value="acegi"/>
<property name="nonceValiditySeconds" value="10" />
</bean>
<bean id="userService" class="com.wallstreetsystems.ws.config.SpringSecurityUserDetailsService">
</bean>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService"/>
</security:authentication-manager>
And the java client is...
public static void main(String args[]) throws Exception {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(OrderNUmber.class);
factory.setAddress(ht..://localh..:9000/ws/OderNumberService);
factory.setUsername("bob");
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.USER,"bob");
outProps.put(WSHandlerConstants.PASSWORD_TYPE,WSConstants.PW_DIGEST);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
factory.getOutInterceptors().add(wssOut);
String orderNo = orderNumber.getNextOrderNumber();
System.out.println(orderNo);
}
I am deploying and running test on embedded Jetty. Error log is as follows....
ID: 1
Address: ht..://localh...:9000/ws/OrderNumberService
Encoding: UTF-8
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=["getNextOrderNumber"]}
Payload: <soap:Envelope xmlns:soap="ht..://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><wsse:UsernameToken wsu:Id="UsernameToken-1"><wsse:Username>bob</wsse:Username><wsse:Password Type="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobspassword</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body/></soap:Envelope>
--------------------------------------
2013-09-23 14:07:36,887 [294071597#qtp-1153274506-2] INFO org.apache.cxf.services.OrderNumberService.OrderNumberPort.OrderNumber - Inbound Message
----------------------------
ID: 2
Address: ht..://localhost:9000/ws/OrderNumberService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[616], content-type=[text/xml; charset=UTF-8], Host=[localhost:9000], Pragma=[no-cache], SOAPAction=["getNextOrderNumber"], User-Agent=[Apache CXF 2.6.2]}
Payload: <soap:Envelope xmlns:soap="ht..://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><wsse:UsernameToken wsu:Id="UsernameToken-1"><wsse:Username>bob</wsse:Username><wsse:Password Type="ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobspassword</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body/></soap:Envelope>
--------------------------------------
2013-09-23 14:07:36,911 [294071597#qtp-1153274506-2] WARN org.apache.cxf.phase.PhaseInterceptorChain - Interceptor for {ht..://www.xyz.com}OrderNumberService#{ht..://www.xyz.com}getNextOrderNumber has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: MustUnderstand headers: [{ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood.
at org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor.checkUltimateReceiverHeaders(MustUnderstandInterceptor.java:150)
at org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor.handleMessage(MustUnderstandInterceptor.java:96)
at org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor.handleMessage(MustUnderstandInterceptor.java:49)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:211)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:213)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:193)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:221)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:141)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:197)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
at com.myproject.ws.config.WSSWebSecurityFilterChain.doFilter(WSSWebSecurityFilterChain.java:64)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1139)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:378)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:535)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:880)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
2013-09-23 14:07:36,940 [main] INFO org.apache.cxf.services.OrderNumberService.OrderNumberPort.OrderNumber - Inbound Message
----------------------------
ID: 1
Response-Code: 500
Encoding: UTF-8
Content-Type: text/xml; charset=utf-8
Headers: {Content-Length=[340], content-type=[text/xml; charset=utf-8], Server=[Jetty(6.1.15)]}
Payload: <soap:Envelope xmlns:soap="ht..://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:MustUnderstand</faultcode><faultstring>MustUnderstand headers: [{ht..://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood.</faultstring></soap:Fault></soap:Body></soap:Envelope>
--------------------------------------
2013-09-23 14:07:37,021 [main] INFO /ws - Closing Spring root WebApplicationContext
Problem : As you can see in the request message header there is no "Authentication [Digest:...." and the request is treated as normal one without auth. But when request reaches service provider which is configured to intercept the Digest request throws the error.
I wanted to set the Authentication type to Digest in the client, so that request would be treated as Digest request.
This is how I fixed it:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("localhost:9000/OrderNumberService");
OrderNumberService orderNumberClient = factory.create(OrderNumberService.class);
Client client = ClientProxy.getClient(orderNumberClient);
HTTPConduit http = (HTTPConduit) client.getConduit();
AuthorizationPolicy authPolicy = new AuthorizationPolicy();
authPolicy.setAuthorizationType("Digest");
authPolicy.setUserName("foo");
authPolicy.setPassword("bar");
http.setAuthorization(authPolicy);
OPTIONS http://localhost:7514/Employees/testrestricted 401 (Unauthorized) angular.js:10419
OPTIONS http://localhost:7514/Employees/testrestricted Origin http://localhost:4064 is not allowed by Access-Control-Allow-Origin. angular.js:10419
XMLHttpRequest cannot load http://localhost:7514/Employees/testrestricted. Origin http://localhost:4064 is not allowed by Access-Control-Allow-Origin.
I have my app.js setup like this already:
var app = angular.module('angular-auth-demo', ['http-auth-interceptor']);
app.config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$routeProvider.
when('/home', { templateUrl: 'partial-content.html', controller: 'ContentController' }).
otherwise({ redirectTo: '/home' });
}]);
is there a way to find out if this is an error on angular or asp.net mvc, because I have a cors configuration on that end too, but i don't think the browser is actually getting a chance to hit the server?
I had a similar issue using Font Awesome cross domain - specifically with Firefox.
Adding a web.config in the directly with the resource you need to access with this solved it for me.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
The request is getting to the server because the server is returning a 401. See the network tab in Chrome dev tools or Firebug. Assuming you have the Access-Control-Allow-Origin header already, you probably need to specify the Access-Control-Allow-Headers header and add Content-Type as its value. Maybe post your CORS config/code?
following solution worked for be:
http://forums.asp.net/t/1885459.aspx
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (this.Context.Request.Path.Contains("signalr/negotiate"))
{
this.Context.Response.AddHeader("Access-Control-Allow-Origin", "*");
this.Context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
this.Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
this.Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}
}