网上有很多关于使用JWT(Json Web Token)进行身份验证的信息.但是,在多域环境中使用JWT令牌作为单点登录解决方案时,我仍然没有找到明确的解释.
我在一家公司工作,该公司在不同的主机上有很多站点.我们使用example1.com和example2.com.我们需要一个单点登录解决方案,这意味着如果用户在example1.com上进行身份验证,我们希望他也可以自动在example2.com上进行身份验证.
使用OpenId Connect流程,我了解想要在example1.com上进行身份验证的用户将首先被重定向到身份验证服务器(或OP"OpenId Provider").用户在该服务器上进行身份验证,然后使用签名的JWT令牌将其重定向回原始example1.com站点.(我知道有另一个流程返回一个中间令牌,以后可以将其交换为真正的JWT令牌,但我不认为这对我们来说是必需的)...
所以现在用户回到example1.com并进行身份验证!他可以发出请求,在Authentication标头中传递JWT令牌,服务器能够验证签名的JWT,因此能够识别用户.太好了!
第一个问题:
如何将JWT令牌存储在客户端上?还有很多关于此的信息,人们似乎同意使用Web Storage是走的路而不是好的旧路cookies.我们希望JWT在浏览器重启之间保持一致,所以让我们使用Local Storage,而不是Session Storage......
现在用户可以重新启动他的浏览器,只要JWT令牌没有过期,他仍然会在example1.com上进行身份验证!
此外,如果example1.com需要向我们的另一个域发出Ajax请求,我理解配置CORS会允许这样做.但我们的主要用例不是跨域请求,它有一个单点登录解决方案!
因此,主要问题是:
现在,流程应该是什么,如果用户访问example2.com并且我们希望他使用他已经拥有的JWT令牌进行身份验证?Local Storage似乎不允许跨域访问,所以此时浏览器无法读取JWT令牌以向example2.com发出请求!
应该 :
我正在开发一个新的Java Web应用程序,我正在探索新的方法(对我来说是新的!)来保存数据.我主要有JPA和Hibernate的经验,但除了简单的情况,我认为这种完整的ORM会变得非常复杂.另外,我不喜欢和他们一起工作.我正在寻找一种新的解决方案,可能更接近SQL.
我正在调查的解决方案:
但与Hibernate相比,我有两个使用案例,我担心这些解决方案.我想知道这些用例的推荐模式是什么.
Person实体.
Person有一个相关的Address实体.
Address有一个相关的City实体.
City实体有一个name属性.从人员实体开始,访问城市名称的完整路径是:
person.address.city.name
Run Code Online (Sandbox Code Playgroud)
现在,假设我PersonService使用以下方法从a加载Person实体:
public Person findPersonById(long id)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用Hibernate,Person可以根据需要延迟加载与之关联的实体,因此可以访问person.address.city.name并确保我可以访问此属性(只要该链中的所有实体都不可为空).
但是使用我正在研究的3种解决方案中的任何一种,它都会更复杂.有了这些解决方案,有哪些推荐的模式来处理这个用例?在前面,我看到3种可能的模式:
可以通过所使用的SQL查询急切地加载所有必需的关联子孙实体.
但是我在这个解决方案中看到的问题是,可能还有一些其他代码需要从实体访问其他实体/属性路径Person.例如,可能需要访问一些代码person.job.salary.currency.如果我想重用findPersonById()我已经拥有的方法,那么SQL查询将需要加载更多信息!不仅是相关address->city实体,还包括相关job->salary实体.
现在如果还有10个其他地方需要从人员实体开始访问其他信息呢?我是否应该急切地加载所有可能需要的信息?或者可能有12种不同的服务方法来加载一个人实体?:
findPersonById_simple(long id)
findPersonById_withAdressCity(long id)
findPersonById_withJob(long id)
findPersonById_withAdressCityAndJob(long id)
...
Run Code Online (Sandbox Code Playgroud)
但是每当我使用一个Person实体时,我就必须知道装载它的是什么以及什么没有...它可能非常麻烦,对吧? …
在我的Spring 3.1应用程序中,我有时需要更改上下文文件中某些Spring命名空间的默认行为.为此,我创建了实现某些接口或扩展Spring使用的默认类的自定义类.
但我发现很难确切知道Spring在其命名空间后面使用的是什么类!找到它们需要哪些步骤?
例如,安全命名空间:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
Run Code Online (Sandbox Code Playgroud)
和类似的东西:
<sec:http>
...
<sec:logout />
</sec:http>
Run Code Online (Sandbox Code Playgroud)
如何找到"<sec:logout />"命名空间使用的类?我没有通过查看http://www.springframework.org/schema/security/spring-security-3.1.xsd找到这些信息!
我应该在哪里看?
我尝试在Postman中编写一个Pre-request脚本.我想提出请求,所以我尝试使用pm.sendRequest.例如 :
pm.sendRequest('http://example.com', function (err, res) {
//...
});
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:
There was an error in evaluating the Pre-request Script: pm is not defined
我在Windows 10上.我刚刚更新了扩展程序.
我如何访问pm?
我创建了一个npm在一些根项目中使用的自定义库.该库是用TypeScript编写的.所有来源都在一个/src文件夹下.
该tsconfig.json库包含那些编译器选项:
"sourceMap": true
"outDir": "dist"
Run Code Online (Sandbox Code Playgroud)
该package.json文件包含:
"main": "dist/src/index.js",
"typings": "dist/src",
"files": [
"src",
"dist"
],
Run Code Online (Sandbox Code Playgroud)
最后,生成的包包含生成的.js文件,d.ts文件和.ts源文件:
- package.json
- /dist (`.js` and `d.ts` files)
- /src (`.ts` files)
Run Code Online (Sandbox Code Playgroud)
在已安装此自定义库的根项目中,我可以在调用从库导入的函数的行上添加断点,然后单步调试它以调试其代码,所有这些都在TypeScript中.这很棒!
但是,在Visual Studio代码中,当我按CTRL-单击从库导入的函数而不进行调试时,它会将我引导到d.ts类型定义文件.我会prefere它带领到.ts源文件!目前的方式,如果我需要查看实际的源代码,我必须自己浏览/src库的文件夹/node_modules.
有没有办法直接在VSCode中转到TypeScript源文件,而不是类型定义文件?
我是Webpack的新手.我尝试使用Webpack主要有两个原因:
require(...)但是我刚开始使用的应用程序(目前只有四个React组件),bundle.jsWebpack生成的文件是3.87Mb!
我很确定Webpack捆绑了我不需要的东西.我想知道如何优化生成的文件......如何"调试"Webpack的进程?
我的webpack.config.js:
var webpack = require("webpack");
module.exports = {
entry: "./app/bootstrap.js",
output: {
path: __dirname,
publicPath: "/public/",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader'
},
{
test: /\.js$/,
include: /vis/,
loader: 'babel-loader'
},
{
test: /\.(png|woff|woff2|eot|ttf|svg|gif|jpg|jpeg|bmp)(\?.*$|$)/,
loader: 'url-loader?limit=100000'
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
}),
new webpack.optimize.UglifyJsPlugin({minimize: true})
] …Run Code Online (Sandbox Code Playgroud) 我想使用Java 8 的新方法引用在编译时提供一些代码的更多验证.
假设我有一个validateMethod方法需要一个参数:要验证的"方法".例如 :
validateMethod(foo, "methodA");
Run Code Online (Sandbox Code Playgroud)
这里,该方法将在运行时验证foo#methodA()存在.
使用方法引用,我希望能够:
validateMethod(foo::methodA);
Run Code Online (Sandbox Code Playgroud)
因此,该方法的存在将在编译时验证.
问题是似乎必须将方法引用分配给功能接口.例如,这个:
Object dummy = foo::methodA;
Run Code Online (Sandbox Code Playgroud)
生成错误:" 此表达式的目标类型必须是功能接口 ".
如果我创建一个与该methodA方法具有兼容签名的功能接口,它可以工作:
@FunctionalInterface
public interface MyFunctionalInterface
{
public String run();
}
MyFunctionalInterface dummy = foo::methodA;
Run Code Online (Sandbox Code Playgroud)
现在存在的foo#methodA()是在编译时验证的,这就是我想要的!
但...
假设validateMethod不知道它必须验证的方法的签名.那么它仍然可以实现吗?
让我们假装我们不关心歧义和重载方法.在Java 8中是否可以实现某种方法来触发任何方法引用的验证?
例如 :
public class Foo
{
public String methodA()
{
return "methodA";
}
public String methodB(String str)
{
return "methodB";
}
public …Run Code Online (Sandbox Code Playgroud) 我目前用我的.tag文件声明:
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
Run Code Online (Sandbox Code Playgroud)
标记文件路径的示例:
/WEB-INF/tags/test.tag
Run Code Online (Sandbox Code Playgroud)
我这样使用它们:
<t:test oneAttributeKey="oneAttributeValue">
some content...
</t:test>
Run Code Online (Sandbox Code Playgroud)
我的问题:我不想把我的所有标签文件都放在一个文件夹"/ WEB-INF/tags"中.
我宁愿把它们放在不同的子目录中:
/ WEB-INF /标签/用户/
/ WEB-INF /标签/ widgetsA /
/ WEB-INF /标签/ widgetsB /
(......)
这是否可行,而不为每个人和每个人创建不同的taglib前缀?
我想避免的例子:
<%@taglib prefix="t_users" tagdir="/WEB-INF/tags/users" %>
<%@taglib prefix="t_widgetsA" tagdir="/WEB-INF/tags/widgetsA" %>
<%@taglib prefix="t_widgetsB" tagdir="/WEB-INF/tags/widgetsB" %>
Run Code Online (Sandbox Code Playgroud)
我希望使用单个"t"前缀的示例:
<t:users/onetag oneAttributeKey="oneAttributeValue">
some content...
</t:users/onetag>
Run Code Online (Sandbox Code Playgroud)
是否存在类似的解决方案?
更新:BalusC表明,通过在单个.tld中定义所有标记文件,可以只使用一个前缀.我想我的问题还不够明确:我想知道是否可以在多个子目录中使用标记文件,而不必在任何地方指定路径,除非在使用它们的元素中(例如: <T:用户/ onetag")!
我不喜欢JSP标签的是它们的行为与普通的JSP文件非常不同,即使它们实际上共享非常相似的内容.事实上,我甚至决定将所有jsp文件放在/ WEB-INF/tags /文件夹中,因此它们与标记文件并排(我必须选择/ WEB-INF/tags /,因为这文件夹对于标记文件是必需的,由于某种原因)!我不明白为什么我的一些包含HTML的文件会放在/ WEB-INF/jsp /和其他一些/ WEB-INF/tags/!!
我希望能够将jsp和标记文件分组到目录中,具体取决于它们的相关内容!示例:
/WEB-INF/tags/users/userProfileLayout.tag
/WEB-INF/tags/users/employeeProfile.jsp
/WEB-INF/tags/users/employerProfile.jsp
/WEB-INF/tags/widgetsA/widgetALayout.tag
/WEB-INF/tags/widgetsA/oldWidgetA.jsp
/WEB-INF/tags/widgetsA/newWidgetA.jsp
Run Code Online (Sandbox Code Playgroud)
但这迫使我在多个@tablib或.tld中声明每个子目录的路径,我觉得这有点不方便.我会忍受它,但我认为它可以改进.
在Spring MVC 3.1应用程序中,我正在尝试实现一个remember-me功能(信息保存在数据库中).
这是我现在拥有的:
我在我的安全上下文文件中有这个:
<form-login login-page="/login"
authentication-failure-url="/login?err=true"
default-target-url="/"
username-parameter="username"
password-parameter="password"
login-processing-url="/validatelogin" />
<remember-me key="some_random_key"
token-validity-seconds="31536000"
data-source-ref="dataSource" />
Run Code Online (Sandbox Code Playgroud)在我的login.jsp中,我有:
<form action="/validatelogin" method="post">
username : <input type='text' id='username' name='username' value='${SPRING_SECURITY_LAST_EXCEPTION.authentication.principal}' />
<br />
password : <input type='password' id='password' name='password' />
<br /><br />
remember me : <input type="checkbox" name="_spring_security_remember_me" />
<br /><br />
<input type="submit" value="submit" />
</form>
Run Code Online (Sandbox Code Playgroud)在"<form-login>"bean中,我已经能够使用username-parameter和password-parameter重命名必须在jsp中使用的默认"j_password"和"j_username"字段.但我找不到重命名"_spring_security_remember_me"复选框字段的方法.
有关如何重命名它的任何想法?