Spring Security OAuth2 - Anonymous-only endpoint - spring-security-oauth2

How can I make an endpoint accessible only to anonymous users? I tried
http
.authorizeRequests()
.regexMatchers(HttpMethod.POST, "^/users$")
.anonymous()
and
http
.authorizeRequests()
.regexMatchers(HttpMethod.POST, "^/users$")
.hasAnyAuthority("ROLE_ANONYMOUS");
but I always end up getting the following message:
An Authentication object was not found in the SecurityContext
In case that matters, my last rule is
http
.authorizeRequests()
.anyRequest()
.denyAll();
so as to forbid access to every non-configured endpoint by default.
Update: Following Dave Syer's suggestion, I merged every rule in the same chain, but I keep getting the same message. These are my rules right now:
http.authorizeRequests()
.regexMatchers(HttpMethod.POST, "^/users$")
.anonymous()
.regexMatchers(HttpMethod.GET, "^/me$")
.hasAnyAuthority("ROLE_ADMIN", "ROLE_USER")
.anyRequest()
.denyAll();
Any suggestion?

When you call http.authorizeRequests() you reset the rules, so normally you would only call it once per configuration. I think you just need to merge your anonymous rules with your anyRequest() on the same chain of authorizeRequests().

Related

Disable Only HealthCheck Related Logging

I'm trying to figure out a way to disable any health-check related ILogger logging. I am aware of LogLevel filtering, but that will not work here.
As an example, I have a healthcheck that makes an outbound call to a RabbitMQ metrics API. This results in an outbound http call with every inbound call to /health. In general, I want to log all outbound calls made using the HttpClient, but that log is now full of this particular log entry:
[2021.06.15 13:57:04] info: System.Net.Http.HttpClient.Default.LogicalHandler[101] => ConnectionId:0HM9FV5PFFL5K => RequestPath:/health RequestId:0HM9FV5PFFL5K:00000001, SpanId:|6726c52-4217ec92de4df5fb., TraceId:6726c52-4217ec92de4df5fb, ParentId: => Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckLogScope => HTTP GET http://rabbitmq/api/queues/MyVHost/MyQueue?msg_rates_age=60&msg_rates_incr=60
: End processing HTTP request after 4.6355ms - OK
So, I could apply a warning filter to the HttpClient/LogicalHandler to remove those entries, but then I'd be removing all the info logs of other outbound Http requests, which I don't want.
So, basically, I need a smarter filter that can look at the scopes (or even the text in certain cases), and can filter out based on "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckLogScope". That doesn't seem to be possible though, as the filter callback doesn't provide those details.
Does anyone have any idea how to do more specific log filtering for cases like this?
I have looked at .net core log filtering on certain requests, but extending every ILoggerProvider I use isn't possible, since some are not public classes.
You could use Serilog for logging, as it also provides great filtering, enriching, and formatting capabilities with Serilog.Expressions Nuget package.
There is even a simple example provided in the link above for filtering health checks, which fulfilled my needs to fully filter out health check logging based on the request path '/health'. Following the guide, it only required adding appsettings.json configuration, after the serilog was configured as the application logger to make it work:
{
"Serilog": {
"Using": ["Serilog.Expressions"],
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "RequestPath like '/health%'"
}
}
]
}
}
To filter out those requests you can try using the Log4Net StringMatchFilter filter with the value of the health URL.
Here is the code for the configuration file if health URL is just localhost/health:
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="/health" />
<acceptOnMatch value="false" />
</filter>

Error During PingFederate Agentless Sequence

Some of our users are encountering the following error page during the sequence of redirects after authenticating at their IdP.
"Unexpected exception occurred in Response Handling: null"
Partner: ...
Target: ...
This is what I believe is the corresponding info from the the server log.
2015-07-16 07:48:53,458 DEBUG [com.pingidentity.jgroups.MuxInvocationHandler] invocation of saveState on InterReqStateMgmtMapImpl state map size:215 attributes map size4 w/args: [ZkyN3LwNSjurZyfIewu1Kgjbgl7HrB, State(1437050933419){
inMsgCtx=null
outMsgCtx=OutMessageContext
XML: <samlp:AuthnRequest Version="2.0" ID="E6_0yldGrt0iqNKfUpArog6DG8G" IssueInstant="2015-07-16T12:48:53.419Z" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">#issuer%</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true"/>
</samlp:AuthnRequest>
entityId: <Id> (IDP)
Binding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
relayState: ZkyN3LwNSjurZyfIewu1Kgjbgl7HrB
Endpoint: <endpoint>
SignaturePolicy: DO_NOT_SIGN
parameters=null}] returned null
Is there an obvious place to look for more details? This happens for around 10% of our users and seems to follow them from device to device.
I figured out what the issue was. We are using account linking using the SAML Subject from the IdP. It turned out that a number of accounts at the IdP didn't have the LDAP attribute mapped to the NameID populated. So we were receiving SAML assertions without any data in the Subject.
Understanding where to look is the key. The audit.log file shows a general "failure". Then you look up corresponding activity details in the server.log file. Then you examine the corresponding SAML assertion in the log to determine what the problem was. The difficult part is noticing omissions in the data. That's harder for the eye/brain to catch imho.
It would be useful if we had an option for directing users to a custom page rather than a Ping-specific error page when this occurs.

Apigee fault handling for CLASSIFICATION_FAILURE

In Apigee, can fault handling - specifying a FaultRule and a RaiseFault policy be used to handle and provide a custom message for:
{
"fault": {
"faultstring": "Not Found",
"detail": {
"errorcode": "CLASSIFICATION_FAILURE"
}
}
}
If this can be done, should the 'Condition' for the fault rule be 'fault.name = "CLASSIFICATION_FAILURE"'? I tried this and it is not working.
CLASSIFICATION_FAILURE is a system level failure to find an API Proxy for the given URL/URI. The request will not even reach the API proxy(hence the policies) - which is the precise complaint by the system.
So you do not want to handle an error like that.
Another way to approach this case is to have a catch all API proxy with basepath /** which will be invoked when there is no specific URL match. You can generate a custom message in this proxy - this can be the message you wanted to send across in case of classification failure.
Srikanth's answer on 30/05/2014 is only partially correct. Using a basepath /** did not work for us. Instead, we had to create an api proxy with basepath = /
Inside the proxy, we defined a RaiseFault in Preflow and that was it.

How to stop consumers from hitting invalid resources in APIGee API

I have an Apigee proxy that has two resources (/resource1 and /resource2). If tried to access /resource3. How do I return a 404 error instead of the Apigee default fault?
Apigee displays the below fault string:
{
"fault": {
"faultstring": "The Service is temporarily unavailable",
"detail": {
"errorcode": "messaging.adaptors.http.flow.ServiceUnavailable"
}
}
}
Thanks
Currently the way flows work in apigee this way - It parses through your default.xml (in proxy) and tries to match your request with one of the flow either through the path-suffix like "/resource1, /resource2" or VERB or any other condition you might have. If it does not find any matching condition, it throws the error like above.
You can add a special flow which will be kicked in if the condition matches none of the valid flows you have. You can add a raisefault policy in that flow and add a custom error response through that flow.
A better solution is to:
be sure to define something in the base path of all Proxy APIs
create an additional Proxy API called "catchall" with a base path of "/" and with just a Raise fault throwing a 404
Apigee execute Proxy APIs from longest Base Path to shortest; the catchall will run last and always throw back a 404
I just want to clarify Vinit's answer. Vinit said:
If it does not find any matching condition, it throws the error like above.
Actually, if no matching flow condition is found, the request will still be sent through to the backend. The error you mentioned:
{
"fault": {
"faultstring": "The Service is temporarily unavailable",
"detail": {
"errorcode": "messaging.adaptors.http.flow.ServiceUnavailable"
}
}
}
was returned after attempting to connect to the backend without matching a flow.
Vinit's solution to raise a fault to create the 404 is the best solution for your requirements.
In some cases, however, it is appropriate to pass all traffic through to the backend (for example, if you don't need to modify each resource at the Apigee layer, and you don't want to have to update your Apigee proxy every time you add a new API resource). Not matching any flow condition would work fine for that use case.

Loading Policies files from https address with flex

I'm having an epic amount of difficulty trying to get a result from a httprequest to a https address.
I'm loading a policy file from the address but I'm still getting the 2048 security error.
I load my policy file like so in my preinitilize handler.
private function preint(e:FlexEvent):void
{
Security.loadPolicyFile("https://api.soundcloud.com/crossdomain.xml");
}
My server gives me back a special token I need and then I try to make a request to the resource I need using a urlrequest and urlloader.
private function getprivatetracks():void
{
var url:String=new String("https://api.soundcloud.com/me/tracks?oauth_token=" + testapplicationparameters["oauth_token"])
var req:URLRequest=new URLRequest()
req.contentType="application/x-www-form-urlencoded"
req.method=URLRequestMethod.GET;
req.url=url;
var loader:URLLoader=new URLLoader()
loader.dataFormat=URLLoaderDataFormat.TEXT;
loader.dataFormat="text";
loader.load(req);
configureListeners(loader);
}
If I trace out the url I'm calling and paste it into a browser I can see the result fine. It's purely a flash thing.
When I run the swf in debug mode from the flex IDE the request works fine. The problem only occurs when the swf is on a server.
I've spend the best part of a day banging my head trying to figure this out.
Could somebody suggest what I might be doing wrong?
I'm guessing I'm lacking some fundamental knowledge about how flash deals with https.
EDIT 1
Error: Request for resource at https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r by requestor from http://myserver/content/flash/soundcloud/sclive.swf is denied due to lack of policy file permissions.
*** Security Sandbox Violation ***
Connection to https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r halted - not permitted from http://myserver/content/flash/soundcloud/sclive.swf
Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: http://myserver/content/flash/soundcloud/sclive.swf cannot load data from https://api.soundcloud.com/me/tracks?oauth_token=0000000NBfKiNXEYG00FWTUGAy5Uw68r.
at sclive/getprivatetracks()[C:\flex_projects\sclive\src\sclive.mxml:74]
at sclive/authorize_result_handler()[C:\flex_projects\sclive\src\sclive.mxml:62]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at HTTPOperation/http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\http\HTTPService.as:763]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::resultHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:263]
at mx.rpc::Responder/result()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\Responder.as:46]
at mx.rpc::AsyncRequest/acknowledge()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:74]
at DirectHTTPMessageResponder/completeHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:409]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
EDIT 2
I've tried catching the security error event and checking the url to make sure theres no redirects going on but the handler never gets called! I always get the unhanled exception error even though I've written a handler for it.
It is not advisable to permit HTTP content to access HTTPS content for security reasons.
So, if soundcloud wants to allow HTTP content to access its data, they should specify it in their crossdomain.xml (using the attribute secure="false" in the allow-access-from tag).
However, I've just noticed there is also a crossdomain on http :
http://api.soundcloud.com/crossdomain.xml
So I suggest you to use this URL instead of the HTTPS and it shloud work

Resources