My ASGI app contains 2 URL pattern series. Some of them require authentication and the rest are available without authentication.
How can I tell them apart when defining ProtocolTypeRouter?
private_urls = [
path("ws/url/one/", FirstConsumer.as_asgi()),
]
public_urls = [
path("ws/url/two/", SecondConsumer.as_asgi()),
path("ws/url/three/", ThirdConsumer.as_asgi()),
]
application = ProtocolTypeRouter(
"http": asgi_app,
# I don't know how to separate them here:
"websocket": URLRouter(public_urls) + JWTAuthMiddlewareStack(URLRouter(private_urls)),
)
Related
Hi I am trying to setup an OAuth provider using this documentation from grails: Grails Documentation
I have done all the steps but when I try to do a request in postman I always got a 404 not found. I have tried many configs and I also tried some different filterChain.chainMap
I also have a MobileController that works fine that I can access in the project. I have tried to copy and paste the filterchain filters to make it the same as on /mobile/ But it still gave me a 404, I have ran the init script (s2-init-oauth2-provider) to make the domain classes
Here is my code that matters for the OAuth provider:
grails-app/conf/application.groovy:
List<String> url_public = [
'/mobile/**',
'/oauth/token'
]
grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/oauth/token', filters: 'JOINED_FILTERS,-oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter'],
[pattern: '/mobile/**', filters: 'JOINED_FILTERS, -securityContextPersistenceFilter, -logoutFilter, -authenticationProcessingFilter, -rememberMeAuthenticationFilter, -oauth2BasicAuthenticationFilter, -exceptionTranslationFilter'],
[pattern: '/**', filters: 'JOINED_FILTERS, -basicAuthenticationFilter, -basicExceptionTranslationFilter, -statelessSecurityContextPersistenceFilter, -oauth2ProviderFilter, -clientCredentialsTokenEndpointFilter, -oauth2BasicAuthenticationFilter, -oauth2ExceptionTranslationFilter'],
]
grails.plugin.springsecurity.oauthProvider.clientLookup.className = 'com.app.oauth.OAuthClient'
grails.plugin.springsecurity.oauthProvider.authorizationCodeLookup.className = 'com.app.oauth.AuthorizationCode'
grails.plugin.springsecurity.oauthProvider.accessTokenLookup.className = 'com.app.oauth.AccessToken'
grails.plugin.springsecurity.oauthProvider.refreshTokenLookup.className = 'com.app.oauth.RefreshToken'
grails-app/init/Bootstrap.groovy:
new OAuthClient(
clientId: 'client_id',
authorizedGrantTypes: ['authorization_code', 'refresh_token', 'implicit', 'password', 'client_credentials'],
authorities: ['ROLE_client'],
scopes: ['read', 'write'],
).save(flush: true)
println "End bootstrap.init "
The fix was that I had to remove the url from the url_public list.
List<String> url_public = [
'/mobile/**'
]
I'm trying to create SwaggerUIBundle where the urls will be of Azure Blob Storage container files.
For testing purpose I have hard coded the urls in here like this in my index.jsp file:
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
urls: [
{url: "https://backendsa.blob.core.windows.net/swagger-consolidation/*****", name: "SwaggerConsolidation"},
{url: "https://backendsa.blob.core.windows.net/swagger-consolidation/*****2", name: "SwaggerConsolidation2"},
],
dom_id: '#swagger-ui',
deepLinking: true,
spec: location.host,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
These urls are pointing SAS urls for Azure Blob Storage files and are accessible while hitting in open network.
But while I deploy the code it gives below error :
Fetch error
NetworkError when attempting to fetch resource. https://backendsa.blob.core.windows.net/swagger-consolidation/*****
Fetch error
Possible cross-origin (CORS) issue? The URL origin (https://backendsa.blob.core.windows.net) does not match the page (https://router-sc.dev-wus.digitalservices.com). Check the server returns the correct 'Access-Control-Allow-*' headers.
Any insight over the issue would be helpful.
According to the error you provide, you need to configure CORS in Azure blob. Because the swaager UI application is a SPA application. when we call the rest api from a domain different from your website in the application, we will get CORS issue. Regarding how to configure it, please refer to the docuemnt.
For example
Allowed origins: *
Allowed verbs: DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT
Allowed headers: *
Exposed headers: *
Maximum age (seconds): 86400
I'm trying to resolve a bigger issue by splitting it into smaller bits. The first problem is that i don't know how to hide properly. for the purpose of this post, i've created a simple demo app that gets deployed to docker (available on github). It has two microservices inside: OcelotGateway (OcelotIdentity project) deployed to localhost:7060 and IdentityServer microservice (Identity project) deployable to localhost:7050. Here's my ocelot configuration file:
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{route}",
"UpstreamPathTemplate": "/identity/{route}",
"UpstreamHttpMethod": [ "Get", "Options", "Post" ],
"DownstreamScheme": "http",
"ServiceName": "identity"
}
],
"GlobalConfiguration": {
"RequestIdKey": "OcRequestId",
"AdministrationPath": "/administration"
}
}
So i expect to see IdentityServer's quickstart page at localhost:7060/identity, but i get 404 instead. This page works fine when i'm reaching it directly at Identity server's url (localhost:7050).
You probably already figured out the answer, but just for future generations; I suppose the problem is your catch-all, that expects something like /identity/something to be passed to /something.
To display the quick-start page, you should define another re-route, that only catches /identity and forwards to /. Then, no something is required and the re-route should work just fine.
Also, the scheme should better be https.
Aim
To include multiple security headers to every request made within the API
Problem
I am trying to add multiple headers to my Swagger YAML security definitions.
I have trawled though the API but not have alot of luck
But am finding that when making the 'Try-This-Operation' I am required to select one. Rather than able to use both. Is this correct or am I doing something incorrectly?
Snippet
securityDefinitions:
userEmail:
type: apiKey
name: User Email
in: header
clientId:
type: apiKey
name: Client Id
in: header
security: [ { userEmail: [], clientId: [] } ]
Alternative?
If I am trying to do this impossible ...
Is it possible to specify these parameters as default for all the rest paths within the swagger document?
I am new to Swagger this week any have found everything else without problem ... but I cannot find any good example of this.
If any guidance could be given that would be incredibly helpful
Many thanks
Your SecurityDefintions object looks ok. Beware that
security: [ { userEmail: [], clientId: [] } ]
means the API client MUST use userEmail authentication AND clientId authentication at once! You probably meant:
security: [ { userEmail: [] }, { clientId: [] } ]
which means the API client MUST use either userEmail authentication OR clientId authentication.
To avoid repeating this definition over and over again you can use the global security property that applies to all paths without their own security object:
security: [ { userEmail: [] }, { clientId: [] } ]
paths:
"/foo":
get:
post:
or make use of a reference for explicitness or for multiple common values:
paths:
"/foo":
get:
security:
"$ref": "#/definitions/lowSecurity"
post:
security:
"$ref": "#/definitions/highSecurity"
definitions:
lowSecurity: [ { foo: [] }, { bar: [] } ]
highSecurity: [ { foo: [] } ]
Reference
The Swagger2 specification states under Operation Object:
security:
[Security Requirement Object]
A declaration of which security schemes are applied for this operation. The list of values describes alternative security schemes that can be used (that is, there is a logical OR between the security requirements). This definition overrides any declared top-level security. To remove a top-level security declaration, an empty array can be used.
The Security Requirement Object is described like this:
Lists the required security schemes to execute this operation. The object can have multiple security schemes declared in it which are all required (that is, there is a logical AND between the schemes).
The name used for each property MUST correspond to a security scheme declared in the Security Definitions.
OAS 3: https://swagger.io/docs/specification/authentication/
Using Multiple Authentication Types
Some REST APIs support several authentication types. The security section lets you combine the security requirements using logical OR and AND to achieve the desired result. security uses the following logic:
security: # A OR B
- A
- B
security: # A AND B
- A
B
security: # (A AND B) OR (C AND D)
- A
B
- C
D
I have configured the dynamic router in the receiver router like below,
dynamicRouter(method("com.eg.DynamicIncomingRoute"), "getIncomingRoute"))
But it is redirecting the request for multiple times to the same bean and the same method.
In the logs it shows like this,
Message History
RouteId ProcessorId Processor Elapsed (ms)
[route3 ] [route3 ] [mina2://tcp://localhost:8888?codec=%23hl7codec&sync=true ] [ 29642]
[route3 ] [dynamicRouter1 ] [dynamicRouter[bean{com.eg.service.handlerService, ] [ 29632]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 11835]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 12776]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 4700]
You can observe the route1 is repeated for multiple times. means it is redirecting to the same method for multiple times. Instead i want to send response back to the user. So how can i do that ?
Read the documentation!
http://camel.apache.org/dynamic-router
See that beware box on that page
Also related is this SO with some details: Dynamic routing in camel en-queues messages infinitely